Merge pull request #23428 from eileenmcnaughton/import_field_keys
[civicrm-core.git] / CRM / Contact / Import / Form / Preview.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
6a488035 5 | |
bc77d7c0
TO
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
6a488035 9 +--------------------------------------------------------------------+
d25dd0ee 10 */
6a488035
TO
11
12/**
13 *
14 * @package CRM
ca5cec67 15 * @copyright CiviCRM LLC https://civicrm.org/licensing
6a488035
TO
16 */
17
18/**
f12c6f7d 19 * This class previews the uploaded file and returns summary statistics.
6a488035 20 */
f532671f 21class CRM_Contact_Import_Form_Preview extends CRM_Import_Form_Preview {
6a488035 22
fd830836
DRJ
23 /**
24 * Whether USPS validation should be disabled during import.
25 *
26 * @var bool
27 */
28 protected $_disableUSPS;
29
6a488035 30 /**
fe482240 31 * Set variables up before form is built.
99e3c5f7
EM
32 *
33 * @throws \API_Exception
34 * @throws \CRM_Core_Exception
6a488035
TO
35 */
36 public function preProcess() {
353ffa53 37 $columnNames = $this->get('columnNames');
fd830836 38 $this->_disableUSPS = $this->get('disableUSPS');
6a488035
TO
39
40 //assign column names
41 $this->assign('columnNames', $columnNames);
42
43 //get the mapping name displayed if the mappingId is set
44 $mappingId = $this->get('loadMappingId');
45 if ($mappingId) {
46 $mapDAO = new CRM_Core_DAO_Mapping();
47 $mapDAO->id = $mappingId;
48 $mapDAO->find(TRUE);
6a488035 49 }
262b7f26 50 $this->assign('savedMappingName', $mappingId ? $mapDAO->name : NULL);
6a488035
TO
51
52 $this->assign('rowDisplayCount', 2);
53
24431f7b 54 $groups = CRM_Core_PseudoConstant::nestedGroup();
6a488035
TO
55 $this->set('groups', $groups);
56
cd43c5e3 57 $tag = CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
6a488035
TO
58 if ($tag) {
59 $this->set('tag', $tag);
60 }
61
99e3c5f7
EM
62 $this->assign('downloadErrorRecordsUrl', $this->getDownloadURL(CRM_Import_Parser::ERROR));
63 $this->assign('invalidRowCount', $this->getRowCount(CRM_Import_Parser::ERROR));
64 $this->assign('validRowCount', $this->getRowCount(CRM_Import_Parser::VALID));
65 $this->assign('totalRowCount', $this->getRowCount([]));
d9839104 66 $this->assign('mapper', $this->getMappedFieldLabels());
99e3c5f7 67 $this->assign('dataValues', $this->getDataRows([], 2));
6a488035 68
8cebffb2 69 $this->setStatusUrl();
6a488035
TO
70 }
71
72 /**
fe482240 73 * Build the form object.
6a488035
TO
74 */
75 public function buildQuickForm() {
c7162176 76 $this->addElement('text', 'newGroupName', ts('Name for new group'), CRM_Core_DAO::getAttribute('CRM_Contact_DAO_Group', 'title'));
6a488035 77 $this->addElement('text', 'newGroupDesc', ts('Description of new group'));
5a552b87
SL
78 $groupTypes = CRM_Core_OptionGroup::values('group_type', TRUE);
79 if (!empty($groupTypes)) {
80 $this->addCheckBox('newGroupType',
81 ts('Group Type'),
82 $groupTypes,
83 NULL, NULL, NULL, NULL, '&nbsp;&nbsp;&nbsp;'
84 );
85 }
6a488035
TO
86
87 $groups = $this->get('groups');
88
89 if (!empty($groups)) {
353ffa53 90 $this->addElement('select', 'groups', ts('Add imported records to existing group(s)'), $groups, array(
69078420
SL
91 'multiple' => "multiple",
92 'class' => 'crm-select2',
93 ));
6a488035
TO
94 }
95
96 //display new tag
c7162176 97 $this->addElement('text', 'newTagName', ts('Tag'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_Tag', 'name'));
98 $this->addElement('text', 'newTagDesc', ts('Description'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_Tag', 'description'));
6a488035
TO
99
100 $tag = $this->get('tag');
101 if (!empty($tag)) {
102 foreach ($tag as $tagID => $tagName) {
103 $this->addElement('checkbox', "tag[$tagID]", NULL, $tagName);
104 }
105 }
106
719a6fec 107 $this->addFormRule(array('CRM_Contact_Import_Form_Preview', 'formRule'), $this);
4c7e1926
CW
108
109 parent::buildQuickForm();
6a488035
TO
110 }
111
112 /**
fe482240 113 * Global validation rules for the form.
6a488035 114 *
77c5b619
TO
115 * @param array $fields
116 * Posted values of the form.
6a488035 117 *
da6b46f4 118 * @param $files
e8cf95b4 119 * @param self $self
da6b46f4 120 *
a6c01b45
CW
121 * @return array
122 * list of errors to be posted back to the form
6a488035 123 */
00be9182 124 public static function formRule($fields, $files, $self) {
affcc9d2 125 $errors = [];
6a488035
TO
126 $invalidTagName = $invalidGroupName = FALSE;
127
a7488080 128 if (!empty($fields['newTagName'])) {
6a488035 129 if (!CRM_Utils_Rule::objectExists(trim($fields['newTagName']),
353ffa53
TO
130 array('CRM_Core_DAO_Tag')
131 )
132 ) {
6a488035
TO
133 $errors['newTagName'] = ts('Tag \'%1\' already exists.',
134 array(1 => $fields['newTagName'])
135 );
136 $invalidTagName = TRUE;
137 }
138 }
139
a7488080 140 if (!empty($fields['newGroupName'])) {
353ffa53
TO
141 $title = trim($fields['newGroupName']);
142 $name = CRM_Utils_String::titleToVar($title);
143 $query = 'select count(*) from civicrm_group where name like %1 OR title like %2';
0e6e8724
DL
144 $grpCnt = CRM_Core_DAO::singleValueQuery(
145 $query,
146 array(
147 1 => array($name, 'String'),
6a488035 148 2 => array($title, 'String'),
0e6e8724
DL
149 )
150 );
6a488035
TO
151 if ($grpCnt) {
152 $invalidGroupName = TRUE;
153 $errors['newGroupName'] = ts('Group \'%1\' already exists.', array(1 => $fields['newGroupName']));
154 }
155 }
156
157 $self->assign('invalidTagName', $invalidTagName);
158 $self->assign('invalidGroupName', $invalidGroupName);
159
160 return empty($errors) ? TRUE : $errors;
161 }
162
6a488035 163 /**
f12c6f7d 164 * Process the mapped fields and map it into the uploaded file.
52bd01f5
EM
165 *
166 * @throws \API_Exception
6a488035
TO
167 */
168 public function postProcess() {
169
170 $importJobParams = array(
171 'doGeocodeAddress' => $this->controller->exportValue('DataSource', 'doGeocodeAddress'),
172 'invalidRowCount' => $this->get('invalidRowCount'),
6a488035 173 'onDuplicate' => $this->get('onDuplicate'),
dfa2f16c 174 'dedupe' => $this->getSubmittedValue('dedupe_rule_id'),
6a488035
TO
175 'newGroupName' => $this->controller->exportValue($this->_name, 'newGroupName'),
176 'newGroupDesc' => $this->controller->exportValue($this->_name, 'newGroupDesc'),
5a552b87 177 'newGroupType' => $this->controller->exportValue($this->_name, 'newGroupType'),
6a488035
TO
178 'groups' => $this->controller->exportValue($this->_name, 'groups'),
179 'allGroups' => $this->get('groups'),
180 'newTagName' => $this->controller->exportValue($this->_name, 'newTagName'),
181 'newTagDesc' => $this->controller->exportValue($this->_name, 'newTagDesc'),
182 'tag' => $this->controller->exportValue($this->_name, 'tag'),
183 'allTags' => $this->get('tag'),
184 'mapper' => $this->controller->exportValue('MapField', 'mapper'),
52bd01f5 185 'mapFields' => $this->getAvailableFields(),
c4f66023 186 'contactType' => $this->getContactType(),
80cb71bb 187 'contactSubType' => $this->getSubmittedValue('contactSubType'),
8d88fae0
EM
188 'primaryKeyName' => '_id',
189 'statusFieldName' => '_status',
6a488035
TO
190 'statusID' => $this->get('statusID'),
191 'totalRowCount' => $this->get('totalRowCount'),
10716b26 192 'userJobID' => $this->getUserJobID(),
6a488035
TO
193 );
194
3377d521 195 $importJob = new CRM_Contact_Import_ImportJob();
6a488035
TO
196 $importJob->setJobParams($importJobParams);
197
198 // If ACL applies to the current user, update cache before running the import.
199 if (!CRM_Core_Permission::check('view all contacts')) {
a92e7856
SL
200 $userID = CRM_Core_Session::getLoggedInContactID();
201 CRM_ACL_BAO_Cache::deleteEntry($userID);
202 CRM_ACL_BAO_Cache::deleteContactCacheEntry($userID);
6a488035
TO
203 }
204
fd830836
DRJ
205 CRM_Utils_Address_USPS::disable($this->_disableUSPS);
206
6a488035
TO
207 // run the import
208 $importJob->runImport($this);
209
16d2a5df 210 // Clear all caches, forcing any searches to recheck the ACLs or group membership as the import
211 // may have changed it.
0626851e 212 CRM_Contact_BAO_Contact_Utils::clearContactCaches(TRUE);
6a488035
TO
213
214 // add all the necessary variables to the form
215 $importJob->setFormVariables($this);
216
b44e3f84 217 // check if there is any error occurred
6a488035
TO
218 $errorStack = CRM_Core_Error::singleton();
219 $errors = $errorStack->getErrors();
affcc9d2 220 $errorMessage = [];
6a488035
TO
221
222 if (is_array($errors)) {
223 foreach ($errors as $key => $value) {
224 $errorMessage[] = $value['message'];
225 }
226
227 // there is no fileName since this is a sql import
228 // so fudge it
229 $config = CRM_Core_Config::singleton();
230 $errorFile = $config->uploadDir . "sqlImport.error.log";
231 if ($fd = fopen($errorFile, 'w')) {
232 fwrite($fd, implode('\n', $errorMessage));
233 }
234 fclose($fd);
235
236 $this->set('errorFile', $errorFile);
6a488035
TO
237 }
238
239 //hack to clean db
240 //if job complete drop table.
91971b3c 241 $importJob->isComplete();
6a488035
TO
242 }
243
d9839104
EM
244 /**
245 * Get the mapped fields as an array of labels.
246 *
247 * e.g
248 * ['First Name', 'Employee Of - First Name', 'Home - Street Address']
249 *
250 * @return array
251 * @throws \API_Exception
252 * @throws \CRM_Core_Exception
253 */
254 protected function getMappedFieldLabels(): array {
255 $mapper = [];
256 $parser = new CRM_Contact_Import_Parser_Contact();
257 $parser->setUserJobID($this->getUserJobID());
258 foreach ($this->getSubmittedValue('mapper') as $columnNumber => $mappedField) {
259 $mapper[$columnNumber] = $parser->getMappedFieldLabel($parser->getMappingFieldFromMapperInput($mappedField, 0, $columnNumber));
260 }
261 return $mapper;
262 }
263
6a488035 264}