/** * check for correct state / country mapping. * * @param array reference $fields - submitted form values. * @param array reference $errors - if any errors found add to this array. please. * * @return true if no errors * array of errors if any present. * * @access public * @static */ static function formRule($fields, $files, $self) { $errors = array(); $customDataRequiredFields = array(); if ($self && property_exists($self, '_addressRequireOmission')) { $customDataRequiredFields = explode(',', $self->_addressRequireOmission); } // check for state/county match if not report error to user. if (!empty($fields['address']) && is_array($fields['address'])) { foreach ($fields['address'] as $instance => $addressValues) { if (CRM_Utils_System::isNull($addressValues)) { // DETACH 'required' form rule error to // custom data only if address data not exists upon submission if (!empty($customDataRequiredFields)) { foreach ($customDataRequiredFields as $customElementName) { $elementName = "address[{$instance}][{$customElementName}]"; if ($self->getElementError($elementName)) { // set element error to none $self->setElementError($elementName, NULL); } } } continue; } // DETACH 'required' form rule error to // custom data only if address data not exists upon submission if (!empty($customDataRequiredFields) && !CRM_Core_BAO_Address::dataExists($addressValues)) { foreach ($customDataRequiredFields as $customElementName) { $elementName = "address[{$instance}][{$customElementName}]"; if ($self->getElementError($elementName)) { // set element error to none $self->setElementError($elementName, NULL); } } } $countryId = CRM_Utils_Array::value('country_id', $addressValues); $stateProvinceId = CRM_Utils_Array::value('state_province_id', $addressValues); //do check for mismatch countries if ($stateProvinceId && $countryId) { $stateProvinceDAO = new CRM_Core_DAO_StateProvince(); $stateProvinceDAO->id = $stateProvinceId; $stateProvinceDAO->find(TRUE); if ($stateProvinceDAO->country_id != $countryId) { // countries mismatch hence display error $stateProvinces = CRM_Core_PseudoConstant::stateProvince(); $countries = CRM_Core_PseudoConstant::country(); $errors["address[{$instance}][state_province_id]"] = ts('State/Province %1 is not part of %2. It belongs to %3.', array(1 => $stateProvinces[$stateProvinceId], 2 => $countries[$countryId], 3 => $countries[$stateProvinceDAO->country_id])); } } $countyId = CRM_Utils_Array::value('county_id', $addressValues); //state county validation if ($stateProvinceId && $countyId) { $countyDAO = new CRM_Core_DAO_County(); $countyDAO->id = $countyId; $countyDAO->find(TRUE); if ($countyDAO->state_province_id != $stateProvinceId) { $counties = CRM_Core_PseudoConstant::county(); $errors["address[{$instance}][county_id]"] = ts('County %1 is not part of %2. It belongs to %3.', array(1 => $counties[$countyId], 2 => $stateProvinces[$stateProvinceId], 3 => $stateProvinces[$countyDAO->state_province_id])); } } if (!empty($addressValues['use_shared_address']) && empty($addressValues['master_id'])) { $errors["address[{$instance}][use_shared_address]"] = ts('Please select valid shared contact or a contact with valid address.'); } } } return empty($errors) ? TRUE : $errors; }
/** * Format the address params to have reasonable values. * * @param array $params * (reference ) an assoc array of name/value pairs. */ public static function fixAddress(&$params) { if (!empty($params['billing_street_address'])) { //Check address is coming from online contribution / registration page //Fixed :CRM-5076 $billing = array('street_address' => 'billing_street_address', 'city' => 'billing_city', 'postal_code' => 'billing_postal_code', 'state_province' => 'billing_state_province', 'state_province_id' => 'billing_state_province_id', 'country' => 'billing_country', 'country_id' => 'billing_country_id'); foreach ($billing as $key => $val) { if ($value = CRM_Utils_Array::value($val, $params)) { if (!empty($params[$key])) { unset($params[$val]); } else { //add new key and removed old $params[$key] = $value; unset($params[$val]); } } } } /* Split the zip and +4, if it's in US format */ if (!empty($params['postal_code']) && preg_match('/^(\\d{4,5})[+-](\\d{4})$/', $params['postal_code'], $match)) { $params['postal_code'] = $match[1]; $params['postal_code_suffix'] = $match[2]; } // add country id if not set if ((!isset($params['country_id']) || !is_numeric($params['country_id'])) && isset($params['country'])) { $country = new CRM_Core_DAO_Country(); $country->name = $params['country']; if (!$country->find(TRUE)) { $country->name = NULL; $country->iso_code = $params['country']; $country->find(TRUE); } $params['country_id'] = $country->id; } // add state_id if state is set if ((!isset($params['state_province_id']) || !is_numeric($params['state_province_id'])) && isset($params['state_province'])) { if (!empty($params['state_province'])) { $state_province = new CRM_Core_DAO_StateProvince(); $state_province->name = $params['state_province']; // add country id if present if (!empty($params['country_id'])) { $state_province->country_id = $params['country_id']; } if (!$state_province->find(TRUE)) { unset($state_province->name); $state_province->abbreviation = $params['state_province']; $state_province->find(TRUE); } $params['state_province_id'] = $state_province->id; if (empty($params['country_id'])) { // set this here since we have it $params['country_id'] = $state_province->country_id; } } else { $params['state_province_id'] = 'null'; } } // add county id if county is set // CRM-7837 if ((!isset($params['county_id']) || !is_numeric($params['county_id'])) && isset($params['county']) && !empty($params['county'])) { $county = new CRM_Core_DAO_County(); $county->name = $params['county']; if (isset($params['state_province_id'])) { $county->state_province_id = $params['state_province_id']; } if ($county->find(TRUE)) { $params['county_id'] = $county->id; } } // currently copy values populates empty fields with the string "null" // and hence need to check for the string null if (isset($params['state_province_id']) && is_numeric($params['state_province_id']) && (!isset($params['country_id']) || empty($params['country_id']))) { // since state id present and country id not present, hence lets populate it // jira issue http://issues.civicrm.org/jira/browse/CRM-56 $params['country_id'] = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_StateProvince', $params['state_province_id'], 'country_id'); } //special check to ignore non numeric values if they are not //detected by formRule(sometimes happens due to internet latency), also allow user to unselect state/country if (isset($params['state_province_id'])) { if (empty($params['state_province_id'])) { $params['state_province_id'] = 'null'; } elseif (!is_numeric($params['state_province_id']) || (int) $params['state_province_id'] < 1000) { // CRM-3393 ( the hacky 1000 check) $params['state_province_id'] = 'null'; } } if (isset($params['country_id'])) { if (empty($params['country_id'])) { $params['country_id'] = 'null'; } elseif (!is_numeric($params['country_id']) || (int) $params['country_id'] < 1000) { // CRM-3393 ( the hacky 1000 check) $params['country_id'] = 'null'; } } // add state and country names from the ids if (isset($params['state_province_id']) && is_numeric($params['state_province_id'])) { $params['state_province'] = CRM_Core_PseudoConstant::stateProvinceAbbreviation($params['state_province_id']); } if (isset($params['country_id']) && is_numeric($params['country_id'])) { $params['country'] = CRM_Core_PseudoConstant::country($params['country_id']); } $config = CRM_Core_Config::singleton(); $asp = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::ADDRESS_STANDARDIZATION_PREFERENCES_NAME, 'address_standardization_provider'); // clean up the address via USPS web services if enabled if ($asp === 'USPS' && $params['country_id'] == 1228) { CRM_Utils_Address_USPS::checkAddress($params); // do street parsing again if enabled, since street address might have changed $parseStreetAddress = CRM_Utils_Array::value('street_address_parsing', CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'address_options'), FALSE); if ($parseStreetAddress && !empty($params['street_address'])) { foreach (array('street_number', 'street_name', 'street_unit', 'street_number_suffix') as $fld) { unset($params[$fld]); } // main parse string. $parseString = CRM_Utils_Array::value('street_address', $params); $parsedFields = CRM_Core_BAO_Address::parseStreetAddress($parseString); // merge parse address in to main address block. $params = array_merge($params, $parsedFields); } } // add latitude and longitude and format address if needed if (!empty($config->geocodeMethod) && $config->geocodeMethod != 'CRM_Utils_Geocode_OpenStreetMaps' && empty($params['manual_geo_code'])) { $class = $config->geocodeMethod; $class::format($params); } }
/** * check for correct state / country mapping. * * @param array reference $fields - submitted form values. * @param array reference $errors - if any errors found add to this array. please. * * @return true if no errors * array of errors if any present. * * @access public * @static */ static function formRule($fields) { $errors = array(); // check for state/county match if not report error to user. if (CRM_Utils_Array::value('address', $fields) && is_array($fields['address'])) { foreach ($fields['address'] as $instance => $addressValues) { if (CRM_Utils_System::isNull($addressValues)) { continue; } $countryId = CRM_Utils_Array::value('country_id', $addressValues); $stateProvinceId = CRM_Utils_Array::value('state_province_id', $addressValues); //do check for mismatch countries if ($stateProvinceId && $countryId) { $stateProvinceDAO = new CRM_Core_DAO_StateProvince(); $stateProvinceDAO->id = $stateProvinceId; $stateProvinceDAO->find(TRUE); if ($stateProvinceDAO->country_id != $countryId) { // countries mismatch hence display error $stateProvinces = CRM_Core_PseudoConstant::stateProvince(); $countries = CRM_Core_PseudoConstant::country(); $errors["address[{$instance}][state_province_id]"] = ts('State/Province %1 is not part of %2. It belongs to %3.', array(1 => $stateProvinces[$stateProvinceId], 2 => $countries[$countryId], 3 => $countries[$stateProvinceDAO->country_id])); } } $countyId = CRM_Utils_Array::value('county_id', $addressValues); //state county validation if ($stateProvinceId && $countyId) { $countyDAO = new CRM_Core_DAO_County(); $countyDAO->id = $countyId; $countyDAO->find(TRUE); if ($countyDAO->state_province_id != $stateProvinceId) { $counties = CRM_Core_PseudoConstant::county(); $errors["address[{$instance}][county_id]"] = ts('County %1 is not part of %2. It belongs to %3.', array(1 => $counties[$countyId], 2 => $stateProvinces[$stateProvinceId], 3 => $stateProvinces[$countyDAO->state_province_id])); } } if (CRM_Utils_Array::value('use_shared_address', $addressValues) && !CRM_Utils_Array::value('master_id', $addressValues)) { $errors["address[{$instance}][use_shared_address]"] = ts('Please select valid shared contact or a contact with valid address.'); } } } return empty($errors) ? TRUE : $errors; }
/** * Global form rule. * * @param array $fields * The input form values. * @param array $files * The uploaded files if any. * @param CRM_Core_Form $form * The form object. * * @return bool|array * true if no errors, else array of errors */ public static function formRule($fields, $files, $form) { CRM_Utils_Hook::validateProfile($form->_ufGroup['name']); $errors = array(); // if no values, return if (empty($fields)) { return TRUE; } $register = NULL; // hack we use a -1 in options to indicate that its registration if ($form->_id) { $form->_isUpdateDupe = 1; } if ($form->_mode == CRM_Profile_Form::MODE_REGISTER) { $register = TRUE; } // dont check for duplicates during registration validation: CRM-375 if (!$register && empty($fields['_qf_Edit_upload_duplicate'])) { // fix for CRM-3240 if (!empty($fields['email-Primary'])) { $fields['email'] = CRM_Utils_Array::value('email-Primary', $fields); } // fix for CRM-6141 if (!empty($fields['phone-Primary-1']) && empty($fields['phone-Primary'])) { $fields['phone-Primary'] = $fields['phone-Primary-1']; } $ctype = CRM_Core_BAO_UFGroup::getContactType($form->_gid); // If all profile fields is of Contact Type then consider // profile is of Individual type(default). if (!$ctype) { $ctype = 'Individual'; } $dedupeParams = CRM_Dedupe_Finder::formatParams($fields, $ctype); if ($form->_mode == CRM_Profile_Form::MODE_CREATE) { // fix for CRM-2888 $exceptions = array(); } else { // for edit mode we need to allow our own record to be a dupe match! $exceptions = array($form->_session->get('userID')); } // for dialog mode we should always use fuzzy rule. $ruleType = 'Unsupervised'; if ($form->_context == 'dialog') { $ruleType = 'Supervised'; } $dedupeParams['check_permission'] = FALSE; $ids = CRM_Dedupe_Finder::dupesByParams($dedupeParams, $ctype, $ruleType, $exceptions, $form->_ruleGroupID); if ($ids) { if ($form->_isUpdateDupe == 2) { CRM_Core_Session::setStatus(ts('Note: this contact may be a duplicate of an existing record.'), ts('Possible Duplicate Detected'), 'alert'); } elseif ($form->_isUpdateDupe == 1) { if (!$form->_id) { $form->_id = $ids[0]; } } else { if ($form->_context == 'dialog') { $contactLinks = CRM_Contact_BAO_Contact_Utils::formatContactIDSToLinks($ids, TRUE, TRUE); $duplicateContactsLinks = '<div class="matching-contacts-found">'; $duplicateContactsLinks .= ts('One matching contact was found. ', array('count' => count($contactLinks['rows']), 'plural' => '%count matching contacts were found.<br />')); if ($contactLinks['msg'] == 'view') { $duplicateContactsLinks .= ts('You can View the existing contact.', array('count' => count($contactLinks['rows']), 'plural' => 'You can View the existing contacts.')); } else { $duplicateContactsLinks .= ts('You can View or Edit the existing contact.', array('count' => count($contactLinks['rows']), 'plural' => 'You can View or Edit the existing contacts.')); } $duplicateContactsLinks .= '</div>'; $duplicateContactsLinks .= '<table class="matching-contacts-actions">'; $row = ''; for ($i = 0; $i < count($contactLinks['rows']); $i++) { $row .= ' <tr> '; $row .= ' <td class="matching-contacts-name"> '; $row .= $contactLinks['rows'][$i]['display_name']; $row .= ' </td>'; $row .= ' <td class="matching-contacts-email"> '; $row .= $contactLinks['rows'][$i]['primary_email']; $row .= ' </td>'; $row .= ' <td class="action-items"> '; $row .= $contactLinks['rows'][$i]['view'] . ' '; $row .= $contactLinks['rows'][$i]['edit']; $row .= ' </td>'; $row .= ' </tr> '; } $duplicateContactsLinks .= $row . '</table>'; $duplicateContactsLinks .= "If you're sure this record is not a duplicate, click the 'Save Matching Contact' button below."; $errors['_qf_default'] = $duplicateContactsLinks; // let smarty know that there are duplicates $template = CRM_Core_Smarty::singleton(); $template->assign('isDuplicate', 1); } else { $errors['_qf_default'] = ts('A record already exists with the same information.'); } } } } foreach ($fields as $key => $value) { list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System::explode('-', $key, 3); if ($fieldName == 'state_province' && !empty($fields["country-{$locTypeId}"])) { // Validate Country - State list $countryId = $fields["country-{$locTypeId}"]; $stateProvinceId = $value; if ($stateProvinceId && $countryId) { $stateProvinceDAO = new CRM_Core_DAO_StateProvince(); $stateProvinceDAO->id = $stateProvinceId; $stateProvinceDAO->find(TRUE); if ($stateProvinceDAO->country_id != $countryId) { // country mismatch hence display error $stateProvinces = CRM_Core_PseudoConstant::stateProvince(); $countries = CRM_Core_PseudoConstant::country(); $errors[$key] = "State/Province " . $stateProvinces[$stateProvinceId] . " is not part of " . $countries[$countryId] . ". It belongs to " . $countries[$stateProvinceDAO->country_id] . "."; } } } if ($fieldName == 'county' && $fields["state_province-{$locTypeId}"]) { // Validate County - State list $stateProvinceId = $fields["state_province-{$locTypeId}"]; $countyId = $value; if ($countyId && $stateProvinceId) { $countyDAO = new CRM_Core_DAO_County(); $countyDAO->id = $countyId; $countyDAO->find(TRUE); if ($countyDAO->state_province_id != $stateProvinceId) { // state province mismatch hence display error $stateProvinces = CRM_Core_PseudoConstant::stateProvince(); $counties = CRM_Core_PseudoConstant::county(); $errors[$key] = "County " . $counties[$countyId] . " is not part of " . $stateProvinces[$stateProvinceId] . ". It belongs to " . $stateProvinces[$countyDAO->state_province_id] . "."; } } } } foreach (CRM_Contact_BAO_Contact::$_greetingTypes as $greeting) { if ($greetingType = CRM_Utils_Array::value($greeting, $fields)) { $customizedValue = CRM_Core_OptionGroup::getValue($greeting, 'Customized', 'name'); if ($customizedValue == $greetingType && empty($fields[$greeting . '_custom'])) { $errors[$greeting . '_custom'] = ts('Custom %1 is a required field if %1 is of type Customized.', array(1 => ucwords(str_replace('_', ' ', $greeting)))); } } } return empty($errors) ? TRUE : $errors; }
/** * check for correct state / country mapping. * * @param array reference $fields - submitted form values. * @param array reference $errors - if any errors found add to this array. please. * @return true if no errors * array of errors if any present. * * @access public * @static */ static function formRule($fields, $errors) { $errors = array(); // check for state/county match if not report error to user. if (is_array($fields['address'])) { foreach ($fields['address'] as $instance => $addressValues) { if (CRM_Utils_System::isNull($addressValues)) { continue; } if ($countryId = CRM_Utils_Array::value('country_id', $addressValues)) { if (!array_key_exists($countryId, CRM_Core_PseudoConstant::country())) { $countryId = null; $errors["address[{$instance}][country_id]"] = ts('Enter a valid country name.'); } } if ($stateProvinceId = CRM_Utils_Array::value('state_province_id', $addressValues)) { // hack to skip - type first letter(s) - for state_province // CRM-2649 if ($stateProvinceId != ts('- type first letter(s) -')) { if (!array_key_exists($stateProvinceId, CRM_Core_PseudoConstant::stateProvince(false, false))) { $stateProvinceId = null; $errors["address[{$instance}][state_province_id]"] = ts('Please select a valid State/Province name.'); } } } //do check for mismatch countries if ($stateProvinceId && $countryId) { $stateProvinceDAO = new CRM_Core_DAO_StateProvince(); $stateProvinceDAO->id = $stateProvinceId; $stateProvinceDAO->find(true); if ($stateProvinceDAO->country_id != $countryId) { // countries mismatch hence display error $stateProvinces = CRM_Core_PseudoConstant::stateProvince(); $countries =& CRM_Core_PseudoConstant::country(); $errors["address[{$instance}][state_province_id]"] = ts('State/Province %1 is not part of %2. It belongs to %3.', array(1 => $stateProvinces[$stateProvinceId], 2 => $countries[$countryId], 3 => $countries[$stateProvinceDAO->country_id])); } } $countyId = CRM_Utils_Array::value('county_id', $addressValues); //state county validation if ($stateProvinceId && $countyId) { $countyDAO = new CRM_Core_DAO_County(); $countyDAO->id = $countyId; $countyDAO->find(true); if ($countyDAO->state_province_id != $stateProvinceId) { $counties =& CRM_Core_PseudoConstant::county(); $errors["address[{$instance}][county_id]"] = ts('County %1 is not part of %2. It belongs to %3.', array(1 => $counties[$countyId], 2 => $stateProvinces[$stateProvinceId], 3 => $stateProvinces[$countyDAO->state_province_id])); } } if (CRM_Utils_Array::value('use_shared_address', $addressValues) && !CRM_Utils_Array::value('master_id', $addressValues)) { $errors["address[{$instance}][use_shared_address]"] = ts('Please select valid shared contact or a contact with valid address.'); } } } return empty($errors) ? true : $errors; }