3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2014
37 * This class provides the functionality for batch profile update
39 class CRM_Contact_Form_Task_Batch
extends CRM_Contact_Form_Task
{
42 * The title of the group
49 * Maximum contacts that should be allowed to update
52 protected $_maxContacts = 100;
55 * Maximum profile fields that will be displayed
58 protected $_maxFields = 9;
61 * Variable to store redirect path
64 protected $_userContext;
67 * When not to reset sort_name
69 protected $_preserveDefault = TRUE;
72 * Build all the data structures needed to build the form
77 function preProcess() {
79 * initialize the task and row fields
85 * Build the form object
91 function buildQuickForm() {
92 $ufGroupId = $this->get('ufGroupId');
95 CRM_Core_Error
::fatal('ufGroupId is missing');
97 $this->_title
= ts('Batch Update') . ' - ' . CRM_Core_BAO_UFGroup
::getTitle($ufGroupId);
98 CRM_Utils_System
::setTitle($this->_title
);
100 $this->addDefaultButtons(ts('Save'));
101 $this->_fields
= CRM_Core_BAO_UFGroup
::getFields($ufGroupId, FALSE, CRM_Core_Action
::VIEW
);
103 // remove file type field and then limit fields
104 $suppressFields = FALSE;
105 $removehtmlTypes = array('File', 'Autocomplete-Select');
106 foreach ($this->_fields
as $name => $field) {
107 if ($cfID = CRM_Core_BAO_CustomField
::getKeyID($name) &&
108 in_array($this->_fields
[$name]['html_type'], $removehtmlTypes)
110 $suppressFields = TRUE;
111 unset($this->_fields
[$name]);
115 //FIX ME: phone ext field is added at the end and it gets removed because of below code
116 //$this->_fields = array_slice($this->_fields, 0, $this->_maxFields);
118 $this->addButtons(array(
121 'name' => ts('Update Contact(s)'),
126 'name' => ts('Cancel'),
132 $this->assign('profileTitle', $this->_title
);
133 $this->assign('componentIds', $this->_contactIds
);
135 // if below fields are missing we should not reset sort name / display name
137 $preserveDefaultsArray = array(
138 'first_name', 'last_name', 'middle_name',
139 'organization_name', 'prefix_id', 'suffix_id',
143 foreach ($this->_contactIds
as $contactId) {
144 $profileFields = $this->_fields
;
145 CRM_Core_BAO_Address
::checkContactSharedAddressFields($profileFields, $contactId);
146 foreach ($profileFields as $name => $field) {
147 CRM_Core_BAO_UFGroup
::buildProfile($this, $field, NULL, $contactId);
149 if (in_array($field['name'], $preserveDefaultsArray)) {
150 $this->_preserveDefault
= FALSE;
155 $this->assign('fields', $this->_fields
);
157 // don't set the status message when form is submitted.
158 $buttonName = $this->controller
->getButtonName('submit');
160 if ($suppressFields && $buttonName != '_qf_BatchUpdateProfile_next') {
161 CRM_Core_Session
::setStatus(ts("File or Autocomplete-Select type field(s) in the selected profile are not supported for Batch Update."), ts('Some Fields Excluded'), 'info');
164 $this->addDefaultButtons(ts('Update Contacts'));
165 $this->addFormRule(array('CRM_Contact_Form_Task_Batch', 'formRule'));
169 * Set default values for the form.
175 function setDefaultValues() {
176 if (empty($this->_fields
)) {
180 $defaults = $sortName = array();
181 foreach ($this->_contactIds
as $contactId) {
182 $details[$contactId] = array();
185 $sortName[$contactId] = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
190 CRM_Core_BAO_UFGroup
::setProfileDefaults($contactId, $this->_fields
, $defaults, FALSE);
193 $this->assign('sortName', $sortName);
201 * @param array $fields the input form values
203 * @return true if no errors, else array of errors
207 static function formRule($fields) {
209 $externalIdentifiers = array();
210 foreach ($fields['field'] as $componentId => $field) {
211 foreach ($field as $fieldName => $fieldValue) {
212 if ($fieldName == 'external_identifier') {
213 if (in_array($fieldValue, $externalIdentifiers)) {
214 $errors["field[$componentId][external_identifier]"] = ts('Duplicate value for External ID.');
217 $externalIdentifiers[$componentId] = $fieldValue;
227 * Process the form after the input has been submitted and validated
233 public function postProcess() {
234 $params = $this->exportValues();
236 $ufGroupId = $this->get('ufGroupId');
238 $inValidSubtypeCnt = 0;
239 //send profile notification email if 'notify' field is set
240 $notify = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $ufGroupId, 'notify');
241 foreach ($params['field'] as $key => $value) {
244 //validate subtype before updating
245 if (!empty($value['contact_sub_type']) && !CRM_Contact_BAO_ContactType
::isAllowEdit($key)) {
246 unset($value['contact_sub_type']);
247 $inValidSubtypeCnt++
;
250 $value['preserveDBName'] = $this->_preserveDefault
;
252 //parse street address, CRM-7768
253 self
::parseStreetAddress($value, $this);
255 CRM_Contact_BAO_Contact
::createProfileContact($value, $this->_fields
, $key, NULL, $ufGroupId, NULL, TRUE);
257 $values = CRM_Core_BAO_UFGroup
::checkFieldsEmptyValues($ufGroupId, $key, NULL);
258 CRM_Core_BAO_UFGroup
::commonSendMail($key, $values);
262 CRM_Core_Session
::setStatus('', ts("Updates Saved"), 'success');
263 if ($inValidSubtypeCnt) {
264 CRM_Core_Session
::setStatus(ts('Contact Subtype field of 1 contact has not been updated.', array('plural' => 'Contact Subtype field of %count contacts has not been updated.', 'count' => $inValidSubtypeCnt)), ts('Invalid Subtype'));
269 * Parse street address
270 * @param array $contactValues contact values
271 * @param CRM_Core_Form $form form object
273 public static function parseStreetAddress(&$contactValues, &$form) {
274 if (!is_array($contactValues) ||
!is_array($form->_fields
)) {
278 static $parseAddress;
279 $addressFldKey = 'street_address';
280 if (!isset($parseAddress)) {
281 $parseAddress = FALSE;
282 foreach ($form->_fields
as $key => $fld) {
283 if (strpos($key, $addressFldKey) !== FALSE) {
284 $parseAddress = CRM_Utils_Array
::value('street_address_parsing',
285 CRM_Core_BAO_Setting
::valueOptions(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
295 if (!$parseAddress) {
299 $allParseValues = array();
300 foreach ($contactValues as $key => $value) {
301 if (strpos($key, $addressFldKey) !== FALSE) {
302 $locTypeId = substr($key, strlen($addressFldKey) +
1);
304 // parse address field.
305 $parsedFields = CRM_Core_BAO_Address
::parseStreetAddress($value);
307 //street address consider to be parsed properly,
308 //If we get street_name and street_number.
309 if (empty($parsedFields['street_name']) ||
empty($parsedFields['street_number'])) {
310 $parsedFields = array_fill_keys(array_keys($parsedFields), '');
313 //merge parse values.
314 foreach ($parsedFields as $fldKey => $parseVal) {
316 $fldKey .= "-{$locTypeId}";
318 $allParseValues[$fldKey] = $parseVal;
323 //finally merge all parse values
324 if (!empty($allParseValues)) {
325 $contactValues +
= $allParseValues;