Contact import - extract assignments to be used by other forms
[civicrm-core.git] / CRM / Contact / Import / Form / Preview.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
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 |
9 +--------------------------------------------------------------------+
10 */
11
12 /**
13 *
14 * @package CRM
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
16 */
17
18 /**
19 * This class previews the uploaded file and returns summary statistics.
20 */
21 class CRM_Contact_Import_Form_Preview extends CRM_Import_Form_Preview {
22
23 /**
24 * Whether USPS validation should be disabled during import.
25 *
26 * @var bool
27 */
28 protected $_disableUSPS;
29
30 /**
31 * Set variables up before form is built.
32 *
33 * @throws \API_Exception
34 * @throws \CRM_Core_Exception
35 */
36 public function preProcess() {
37 parent::preProcess();
38 $this->_disableUSPS = $this->getSubmittedValue('disableUSPS');
39
40 $groups = CRM_Core_PseudoConstant::nestedGroup();
41 $this->set('groups', $groups);
42
43 $tag = CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
44 if ($tag) {
45 $this->set('tag', $tag);
46 }
47
48 $this->setStatusUrl();
49 }
50
51 /**
52 * Build the form object.
53 */
54 public function buildQuickForm() {
55 $this->addElement('text', 'newGroupName', ts('Name for new group'), CRM_Core_DAO::getAttribute('CRM_Contact_DAO_Group', 'title'));
56 $this->addElement('text', 'newGroupDesc', ts('Description of new group'));
57 $groupTypes = CRM_Core_OptionGroup::values('group_type', TRUE);
58 if (!empty($groupTypes)) {
59 $this->addCheckBox('newGroupType',
60 ts('Group Type'),
61 $groupTypes,
62 NULL, NULL, NULL, NULL, '&nbsp;&nbsp;&nbsp;'
63 );
64 }
65
66 $groups = $this->get('groups');
67
68 if (!empty($groups)) {
69 $this->addElement('select', 'groups', ts('Add imported records to existing group(s)'), $groups, array(
70 'multiple' => "multiple",
71 'class' => 'crm-select2',
72 ));
73 }
74
75 //display new tag
76 $this->addElement('text', 'newTagName', ts('Tag'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_Tag', 'name'));
77 $this->addElement('text', 'newTagDesc', ts('Description'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_Tag', 'description'));
78
79 $tag = $this->get('tag');
80 if (!empty($tag)) {
81 foreach ($tag as $tagID => $tagName) {
82 $this->addElement('checkbox', "tag[$tagID]", NULL, $tagName);
83 }
84 }
85
86 $this->addFormRule(array('CRM_Contact_Import_Form_Preview', 'formRule'), $this);
87
88 parent::buildQuickForm();
89 }
90
91 /**
92 * Global validation rules for the form.
93 *
94 * @param array $fields
95 * Posted values of the form.
96 *
97 * @param $files
98 * @param self $self
99 *
100 * @return array
101 * list of errors to be posted back to the form
102 */
103 public static function formRule($fields, $files, $self) {
104 $errors = [];
105 $invalidTagName = $invalidGroupName = FALSE;
106
107 if (!empty($fields['newTagName'])) {
108 if (!CRM_Utils_Rule::objectExists(trim($fields['newTagName']),
109 array('CRM_Core_DAO_Tag')
110 )
111 ) {
112 $errors['newTagName'] = ts('Tag \'%1\' already exists.',
113 array(1 => $fields['newTagName'])
114 );
115 $invalidTagName = TRUE;
116 }
117 }
118
119 if (!empty($fields['newGroupName'])) {
120 $title = trim($fields['newGroupName']);
121 $name = CRM_Utils_String::titleToVar($title);
122 $query = 'select count(*) from civicrm_group where name like %1 OR title like %2';
123 $grpCnt = CRM_Core_DAO::singleValueQuery(
124 $query,
125 array(
126 1 => array($name, 'String'),
127 2 => array($title, 'String'),
128 )
129 );
130 if ($grpCnt) {
131 $invalidGroupName = TRUE;
132 $errors['newGroupName'] = ts('Group \'%1\' already exists.', array(1 => $fields['newGroupName']));
133 }
134 }
135
136 $self->assign('invalidTagName', $invalidTagName);
137 $self->assign('invalidGroupName', $invalidGroupName);
138
139 return empty($errors) ? TRUE : $errors;
140 }
141
142 /**
143 * Process the mapped fields and map it into the uploaded file.
144 *
145 * @throws \API_Exception
146 */
147 public function postProcess() {
148
149 $importJobParams = array(
150 'doGeocodeAddress' => $this->getSubmittedValue('doGeocodeAddress'),
151 'invalidRowCount' => $this->getRowCount(CRM_Import_Parser::ERROR),
152 'onDuplicate' => $this->getSubmittedValue('onDuplicate'),
153 'dedupe' => $this->getSubmittedValue('dedupe_rule_id'),
154 'newGroupName' => $this->controller->exportValue($this->_name, 'newGroupName'),
155 'newGroupDesc' => $this->controller->exportValue($this->_name, 'newGroupDesc'),
156 'newGroupType' => $this->controller->exportValue($this->_name, 'newGroupType'),
157 'groups' => $this->controller->exportValue($this->_name, 'groups'),
158 'allGroups' => $this->get('groups'),
159 'newTagName' => $this->controller->exportValue($this->_name, 'newTagName'),
160 'newTagDesc' => $this->controller->exportValue($this->_name, 'newTagDesc'),
161 'tag' => $this->controller->exportValue($this->_name, 'tag'),
162 'allTags' => $this->get('tag'),
163 'mapper' => $this->controller->exportValue('MapField', 'mapper'),
164 'mapFields' => $this->getAvailableFields(),
165 'contactType' => $this->getContactType(),
166 'contactSubType' => $this->getSubmittedValue('contactSubType'),
167 'primaryKeyName' => '_id',
168 'statusFieldName' => '_status',
169 'statusID' => $this->get('statusID'),
170 'totalRowCount' => $this->getRowCount([]),
171 'userJobID' => $this->getUserJobID(),
172 );
173
174 $importJob = new CRM_Contact_Import_ImportJob();
175 $importJob->setJobParams($importJobParams);
176
177 // If ACL applies to the current user, update cache before running the import.
178 if (!CRM_Core_Permission::check('view all contacts')) {
179 $userID = CRM_Core_Session::getLoggedInContactID();
180 CRM_ACL_BAO_Cache::deleteEntry($userID);
181 CRM_ACL_BAO_Cache::deleteContactCacheEntry($userID);
182 }
183
184 CRM_Utils_Address_USPS::disable($this->_disableUSPS);
185
186 // run the import
187 $importJob->runImport($this);
188
189 // Clear all caches, forcing any searches to recheck the ACLs or group membership as the import
190 // may have changed it.
191 CRM_Contact_BAO_Contact_Utils::clearContactCaches(TRUE);
192
193 // add all the necessary variables to the form
194 $importJob->setFormVariables($this);
195
196 // check if there is any error occurred
197 $errorStack = CRM_Core_Error::singleton();
198 $errors = $errorStack->getErrors();
199 $errorMessage = [];
200
201 if (is_array($errors)) {
202 foreach ($errors as $key => $value) {
203 $errorMessage[] = $value['message'];
204 }
205
206 // there is no fileName since this is a sql import
207 // so fudge it
208 $config = CRM_Core_Config::singleton();
209 $errorFile = $config->uploadDir . "sqlImport.error.log";
210 if ($fd = fopen($errorFile, 'w')) {
211 fwrite($fd, implode('\n', $errorMessage));
212 }
213 fclose($fd);
214
215 $this->set('errorFile', $errorFile);
216 }
217
218 //hack to clean db
219 //if job complete drop table.
220 $importJob->isComplete();
221 }
222
223 /**
224 * @return \CRM_Contact_Import_Parser_Contact
225 */
226 protected function getParser(): CRM_Contact_Import_Parser_Contact {
227 if (!$this->parser) {
228 $this->parser = new CRM_Contact_Import_Parser_Contact();
229 $this->parser->setUserJobID($this->getUserJobID());
230 }
231 return $this->parser;
232 }
233
234 }