Remove copy&paste extraneous select
[civicrm-core.git] / CRM / Activity / Import / Form / MapField.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/**
b6c94f42 19 * This class gets the name of the file to upload.
6a488035 20 */
b26295b8 21class CRM_Activity_Import_Form_MapField extends CRM_Import_Form_MapField {
6a488035 22
88aae6d4
A
23 /**
24 * @var bool
25 */
26 public $submitOnce = TRUE;
27
6a488035 28 /**
fe482240 29 * Build the form object.
8bfb13b9 30 *
31 * @throws \CiviCRM_API3_Exception
6a488035
TO
32 */
33 public function buildQuickForm() {
7eebbdaa
EM
34 $savedMappingID = (int) $this->getSubmittedValue('savedMapping');
35 $this->buildSavedMappingFields($savedMappingID);
96f94695 36 $this->addFormRule(['CRM_Activity_Import_Form_MapField', 'formRule']);
6a488035
TO
37
38 //-------- end of saved mapping stuff ---------
39
96f94695 40 $defaults = [];
7eebbdaa
EM
41 $headerPatterns = $this->getHeaderPatterns();
42 $dataPatterns = $this->getDataPatterns();
43 $fieldMappings = $this->getFieldMappings();
44 $columnHeaders = $this->getColumnHeaders();
45 $hasHeaders = $this->getSubmittedValue('skipColumnHeader');
6a488035 46
6a488035
TO
47 $sel1 = $this->_mapperFields;
48
6a488035
TO
49 $js = "<script type='text/javascript'>\n";
50 $formName = 'document.forms.' . $this->_name;
51
7eebbdaa 52 foreach ($columnHeaders as $i => $columnHeader) {
96f94695 53 $sel = &$this->addElement('hierselect', "mapper[$i]", ts('Mapper for Field %1', [1 => $i]), NULL);
6a488035 54 $jsSet = FALSE;
7eebbdaa
EM
55 if ($this->getSubmittedValue('savedMapping')) {
56 $fieldMapping = $fieldMappings[$i] ?? NULL;
57 if (isset($fieldMappings[$i])) {
58 if ($fieldMapping['name'] !== ts('do_not_import')) {
6a488035 59 $js .= "{$formName}['mapper[$i][3]'].style.display = 'none';\n";
7eebbdaa 60 $defaults["mapper[$i]"] = [$fieldMapping['name']];
6a488035
TO
61 $jsSet = TRUE;
62 }
63 else {
96f94695 64 $defaults["mapper[$i]"] = [];
6a488035
TO
65 }
66 if (!$jsSet) {
67 for ($k = 1; $k < 4; $k++) {
68 $js .= "{$formName}['mapper[$i][$k]'].style.display = 'none';\n";
69 }
70 }
71 }
72 else {
73 // this load section to help mapping if we ran out of saved columns when doing Load Mapping
74 $js .= "swapOptions($formName, 'mapper[$i]', 0, 3, 'hs_mapper_" . $i . "_');\n";
75
76 if ($hasHeaders) {
7eebbdaa 77 $defaults["mapper[$i]"] = [$this->defaultFromHeader($columnHeader, $headerPatterns)];
6a488035
TO
78 }
79 else {
96f94695 80 $defaults["mapper[$i]"] = [$this->defaultFromData($dataPatterns, $i)];
6a488035
TO
81 }
82 }
7808aae6 83 // End of load mapping.
6a488035
TO
84 }
85 else {
86 $js .= "swapOptions($formName, 'mapper[$i]', 0, 3, 'hs_mapper_" . $i . "_');\n";
87 if ($hasHeaders) {
88 // Infer the default from the skipped headers if we have them
96f94695 89 $defaults["mapper[$i]"] = [
7eebbdaa 90 $this->defaultFromHeader($columnHeader, $headerPatterns),
6a488035 91 0,
96f94695 92 ];
6a488035
TO
93 }
94 else {
95 // Otherwise guess the default from the form of the data
96f94695 96 $defaults["mapper[$i]"] = [$this->defaultFromData($dataPatterns, $i), 0];
6a488035
TO
97 }
98 }
99
f22d8537 100 $sel->setOptions([$sel1]);
6a488035
TO
101 }
102 $js .= "</script>\n";
103 $this->assign('initHideBoxes', $js);
104
6a488035
TO
105 $this->setDefaults($defaults);
106
96f94695 107 $this->addButtons([
108 [
6a488035 109 'type' => 'back',
f212d37d 110 'name' => ts('Previous'),
96f94695 111 ],
112 [
6a488035 113 'type' => 'next',
f212d37d 114 'name' => ts('Continue'),
6a488035
TO
115 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
116 'isDefault' => TRUE,
96f94695 117 ],
118 [
6a488035
TO
119 'type' => 'cancel',
120 'name' => ts('Cancel'),
96f94695 121 ],
0d48f1cc 122 ]
6a488035
TO
123 );
124 }
125
126 /**
fe482240 127 * Global validation rules for the form.
6a488035 128 *
041ab3d1
TO
129 * @param array $fields
130 * Posted values of the form.
6a488035 131 *
a6c01b45
CW
132 * @return array
133 * list of errors to be posted back to the form
6a488035 134 */
00be9182 135 public static function formRule($fields) {
96f94695 136 $errors = [];
6a488035
TO
137 // define so we avoid notices below
138 $errors['_qf_default'] = '';
139
140 $fieldMessage = NULL;
141 if (!array_key_exists('savedMapping', $fields)) {
96f94695 142 $importKeys = [];
6a488035
TO
143 foreach ($fields['mapper'] as $mapperPart) {
144 $importKeys[] = $mapperPart[0];
145 }
146 // FIXME: should use the schema titles, not redeclare them
96f94695 147 $requiredFields = [
6a488035
TO
148 'target_contact_id' => ts('Contact ID'),
149 'activity_date_time' => ts('Activity Date'),
150 'activity_subject' => ts('Activity Subject'),
bbba2f43 151 'activity_type_id' => ts('Activity Type ID'),
96f94695 152 ];
6a488035 153
02a237ce 154 $contactFieldsBelowWeightMessage = self::validateRequiredContactMatchFields('Individual', $importKeys);
6a488035
TO
155 foreach ($requiredFields as $field => $title) {
156 if (!in_array($field, $importKeys)) {
c5a8afa5 157 if ($field === 'target_contact_id') {
02a237ce 158 if (!$contactFieldsBelowWeightMessage || in_array('external_identifier', $importKeys)) {
6a488035
TO
159 continue;
160 }
161 else {
162 $errors['_qf_default'] .= ts('Missing required contact matching fields.')
02a237ce 163 . $contactFieldsBelowWeightMessage
6a488035
TO
164 . '<br />';
165 }
166 }
c5a8afa5 167 elseif ($field === 'activity_type_id') {
6a488035
TO
168 if (in_array('activity_label', $importKeys)) {
169 continue;
170 }
171 else {
172 $errors['_qf_default'] .= ts('Missing required field: Provide %1 or %2',
96f94695 173 [
353ffa53
TO
174 1 => $title,
175 2 => 'Activity Type Label',
96f94695 176 ]) . '<br />';
6a488035
TO
177 }
178 }
179 else {
96f94695 180 $errors['_qf_default'] .= ts('Missing required field: %1', [1 => $title]) . '<br />';
6a488035
TO
181 }
182 }
183 }
184 }
185
a7488080 186 if (!empty($fields['saveMapping'])) {
9c1bc317 187 $nameField = $fields['saveMappingName'] ?? NULL;
6a488035
TO
188 if (empty($nameField)) {
189 $errors['saveMappingName'] = ts('Name is required to save Import Mapping');
190 }
191 else {
95f52e3b 192 if (CRM_Core_BAO_Mapping::checkMapping($nameField, CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_Mapping', 'mapping_type_id', 'Import Activity'))) {
6a488035
TO
193 $errors['saveMappingName'] = ts('Duplicate Import Mapping Name');
194 }
195 }
196 }
197
198 if (empty($errors['_qf_default'])) {
199 unset($errors['_qf_default']);
200 }
201 if (!empty($errors)) {
202 if (!empty($errors['saveMappingName'])) {
203 $_flag = 1;
204 $assignError = new CRM_Core_Page();
205 $assignError->assign('mappingDetailsError', $_flag);
206 }
207 return $errors;
208 }
209
210 return TRUE;
211 }
212
83a1c234
EM
213 /**
214 * @return CRM_Activity_Import_Parser_Activity
215 */
216 protected function getParser(): CRM_Activity_Import_Parser_Activity {
217 if (!$this->parser) {
218 $this->parser = new CRM_Activity_Import_Parser_Activity();
219 $this->parser->setUserJobID($this->getUserJobID());
220 $this->parser->init();
221 }
222 return $this->parser;
223 }
224
7eebbdaa
EM
225 protected function getHighlightedFields(): array {
226 $highlightedFields = [];
227 $requiredFields = [
228 'activity_date_time',
229 'activity_type_id',
230 'target_contact_id',
231 'activity_subject',
232 ];
233 foreach ($requiredFields as $val) {
234 $highlightedFields[] = $val;
235 }
236 return $highlightedFields;
237 }
238
239 public function getImportType(): string {
240 return 'Import Activity';
241 }
242
243 /**
244 * Get the mapping name per the civicrm_mapping_field.type_id option group.
245 *
246 * @return string
247 */
248 public function getMappingTypeName(): string {
249 return 'Import Participant';
250 }
251
6a488035 252}