Merge pull request #4806 from civicrm/4.5
[civicrm-core.git] / CRM / Custom / Import / Parser / Api.php
1 <?php
2
3 /**
4 * Class CRM_Custom_Import_Parser_Api
5 */
6 class CRM_Custom_Import_Parser_Api extends CRM_Custom_Import_Parser {
7
8 protected $_entity = '';
9 protected $_fields = array();
10 protected $_requiredFields = array();
11 protected $_dateFields = array();
12 protected $_multipleCustomData = '';
13
14 /**
15 * Params for the current entity being prepared for the api
16 * @var array
17 */
18 protected $_params = array();
19 /**
20 * Class constructor
21 */
22 function __construct(&$mapperKeys, $mapperLocType = NULL, $mapperPhoneType = NULL) {
23 parent::__construct();
24 $this->_mapperKeys = &$mapperKeys;
25 }
26 function setFields() {
27 $customGroupID = $this->_multipleCustomData;
28 $importableFields = $this->getGroupFieldsForImport($customGroupID, $this);
29 $this->_fields = array_merge(array('do_not_import' => array('title' => ts('- do not import -')), 'contact_id' => array('title' => ts('Contact ID'))), $importableFields);
30 }
31
32 /**
33 * The initializer code, called before the processing
34 *
35 * @return void
36 * @access public
37 */
38 function init() {
39 $this->setFields();
40 $fields = $this->_fields;
41 $hasLocationType = FALSE;
42
43 foreach ($fields as $name => $field) {
44 $field['type'] = CRM_Utils_Array::value('type', $field, CRM_Utils_Type::T_INT);
45 $field['dataPattern'] = CRM_Utils_Array::value('dataPattern', $field, '//');
46 $field['headerPattern'] = CRM_Utils_Array::value('headerPattern', $field, '//');
47 $this->addField($name, $field['title'], $field['type'], $field['headerPattern'], $field['dataPattern'], $hasLocationType);
48 }
49 $this->setActiveFields($this->_mapperKeys);
50 }
51
52 /**
53 * Handle the values in mapField mode
54 *
55 * @param array $values the array of values belonging to this line
56 *
57 * @return boolean
58 * @access public
59 */
60 function mapField(&$values) {
61 return CRM_Import_Parser::VALID;
62 }
63
64 /**
65 * Handle the values in preview mode
66 *
67 * @param array $values the array of values belonging to this line
68 *
69 * @return boolean the result of this processing
70 * @access public
71 */
72 function preview(&$values) {
73 return $this->summary($values);
74 }
75
76 /**
77 * @param array $values the array of values belonging to this line
78 *
79 * @return boolean the result of this processing
80 * It is called from both the preview & the import actions
81 * (non-PHPdoc)
82 * @see CRM_Custom_Import_Parser_BaseClass::summary()
83 */
84 function summary(&$values) {
85 $erroneousField = NULL;
86 $response = $this->setActiveFieldValues($values, $erroneousField);
87 $errorRequired = FALSE;
88 $missingField = '';
89 $this->_params = &$this->getActiveFieldParams();
90
91 $formatted = $this->_params;
92 $this->_updateWithId = FALSE;
93 $this->_parseStreetAddress = CRM_Utils_Array::value('street_address_parsing', CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'address_options'), FALSE);
94
95 $this->_params = $this->getActiveFieldParams();
96 foreach ($this->_requiredFields as $requiredField) {
97 if (empty($this->_params[$requiredField])) {
98 $errorRequired = TRUE;
99 $missingField .= ' ' . $requiredField;
100 CRM_Contact_Import_Parser_Contact::addToErrorMsg($this->_entity, $requiredField);
101 }
102 }
103
104 if ($errorRequired) {
105 array_unshift($values, ts('Missing required field(s) :') . $missingField);
106 return CRM_Import_Parser::ERROR;
107 }
108
109 $errorMessage = NULL;
110
111 $contactType = $this->_contactType ? $this->_contactType : 'Organization';
112 CRM_Contact_Import_Parser_Contact::isErrorInCustomData($this->_params , $errorMessage, $contactType, NULL);
113
114 // pseudoconstants
115 if ($errorMessage) {
116 $tempMsg = "Invalid value for field(s) : $errorMessage";
117 array_unshift($values, $tempMsg);
118 $errorMessage = NULL;
119 return CRM_Import_Parser::ERROR;
120 }
121 return CRM_Import_Parser::VALID;
122 }
123
124 /**
125 * Handle the values in import mode
126 *
127 * @param int $onDuplicate the code for what action to take on duplicates
128 * @param array $values the array of values belonging to this line
129 *
130 * @return boolean the result of this processing
131 * @access public
132 */
133 function import($onDuplicate, &$values) {
134 $response = $this->summary($values);
135 if ($response != CRM_Import_Parser::VALID) {
136 $importRecordParams = array(
137 $statusFieldName => 'INVALID',
138 "${statusFieldName}Msg" => "Invalid (Error Code: $response)",
139 );
140 return $response;
141 }
142
143 $this->_updateWithId = FALSE;
144 $this->_parseStreetAddress = CRM_Utils_Array::value('street_address_parsing', CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'address_options'), FALSE);
145
146 $params = $this->getActiveFieldParams();
147 $contactType = $this->_contactType ? $this->_contactType : 'Organization';
148 $formatted = array(
149 'contact_type' => $contactType,
150 );
151 $session = CRM_Core_Session::singleton();
152 $dateType = $session->get('dateTypes');
153
154 $formatted['id'] = $this->_params['contact_id'];
155 $setDateFields = array_intersect_key($this->_params, array_flip($this->_dateFields));
156
157 CRM_Contact_Import_Parser_Contact::formatCommonData($this->_params, $formatted, $formatted) ;
158 foreach($formatted['custom'] as $key => $val) {
159 $this->_params['custom_'.$key] = $val[-1]['value'];
160 }
161 $this->_params['skipRecentView'] = TRUE;
162 $this->_params['check_permissions'] = TRUE;
163 $this->_params['entity_id'] = $formatted['id'];
164 try{
165 civicrm_api3('custom_value', 'create', $this->_params);
166 }
167 catch(CiviCRM_API3_Exception $e) {
168 $error = $e->getMessage();
169 array_unshift($values, $error);
170 return CRM_Import_Parser::ERROR;
171 }
172 }
173
174 /**
175 * Format Date params
176 *
177 * Although the api will accept any strtotime valid string CiviCRM accepts at least one date format
178 * not supported by strtotime so we should run this through a conversion
179 */
180 function formatDateParams() {
181 $session = CRM_Core_Session::singleton();
182 $dateType = $session->get('dateTypes');
183 $setDateFields = array_intersect_key($this->_params, array_flip($this->_dateFields));
184
185 foreach ($setDateFields as $key => $value) {
186 CRM_Utils_Date::convertToDefaultDate($this->_params, $dateType, $key);
187 $this->_params[$key] = CRM_Utils_Date::processDate($this->_params[$key]);
188 }
189 }
190
191 /**
192 * Set import entity
193 * @param string $entity
194 */
195 function setEntity($entity) {
196 $this->_entity = $entity;
197 $this->_multipleCustomData = $entity;
198 }
199
200 /**
201 * The initializer code, called before the processing
202 *
203 * @return void
204 * @access public
205 */
206 function fini() {}
207
208 /**
209 * Return the field ids and names (with groups) for import purpose.
210 *
211 * @param int $id Custom group ID
212 *
213 * @return array $importableFields
214 *
215 * @access public
216 * @static
217 */
218 function getGroupFieldsForImport( $id ) {
219 $importableFields = array();
220 $params = array('custom_group_id' => $id);
221 $allFields = civicrm_api3('custom_field', 'get', $params);
222 $fields = $allFields['values'];
223 foreach ($fields as $id => $values) {
224 $datatype = CRM_Utils_Array::value('data_type', $values);
225 if ( $datatype == 'File' ) {
226 continue;
227 }
228 /* generate the key for the fields array */
229 $key = "custom_$id";
230 $regexp = preg_replace('/[.,;:!?]/', '', CRM_Utils_Array::value(0, $values));
231 $importableFields[$key] = array(
232 'name' => $key,
233 'title' => CRM_Utils_Array::value('label', $values),
234 'headerPattern' => '/' . preg_quote($regexp, '/') . '/',
235 'import' => 1,
236 'custom_field_id' => $id,
237 'options_per_line' => CRM_Utils_Array::value('options_per_line', $values),
238 'data_type' => CRM_Utils_Array::value('data_type', $values),
239 'html_type' => CRM_Utils_Array::value('html_type', $values),
240 'is_search_range' => CRM_Utils_Array::value('is_search_range', $values),
241 );
242 if (CRM_Utils_Array::value('html_type', $values) == 'Select Date') {
243 $importableFields[$key]['date_format'] = CRM_Utils_Array::value('date_format', $values);
244 $importableFields[$key]['time_format'] = CRM_Utils_Array::value('time_format', $values);
245 $this->_dateFields[] = $key;
246 }
247 }
248 return $importableFields;
249 }
250 }