Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
bc77d7c0 TO |
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 | +--------------------------------------------------------------------+ | |
e70a7fc0 | 10 | */ |
6a488035 TO |
11 | |
12 | /** | |
13 | * | |
14 | * @package CRM | |
ca5cec67 | 15 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
6a488035 TO |
16 | */ |
17 | ||
18 | /** | |
192d36c5 | 19 | * This class handle creation of location block elements. |
6a488035 TO |
20 | */ |
21 | class CRM_Core_BAO_Location extends CRM_Core_DAO { | |
22 | ||
23 | /** | |
fe482240 | 24 | * Location block element array. |
518fa0ee | 25 | * @var array |
6a488035 | 26 | */ |
518fa0ee | 27 | public static $blocks = ['phone', 'email', 'im', 'openid', 'address']; |
6a488035 TO |
28 | |
29 | /** | |
fe482240 | 30 | * Create various elements of location block. |
6a488035 | 31 | * |
6a0b768e TO |
32 | * @param array $params |
33 | * (reference ) an assoc array of name/value pairs. | |
34 | * @param bool $fixAddress | |
35 | * True if you need to fix (format) address values. | |
6a488035 TO |
36 | * before inserting in db |
37 | * | |
77b97be7 EM |
38 | * @param null $entity |
39 | * | |
a6c01b45 | 40 | * @return array |
6a488035 | 41 | */ |
00be9182 | 42 | public static function create(&$params, $fixAddress = TRUE, $entity = NULL) { |
be2fb01f | 43 | $location = []; |
6a488035 TO |
44 | if (!self::dataExists($params)) { |
45 | return $location; | |
46 | } | |
47 | ||
48 | // create location blocks. | |
49 | foreach (self::$blocks as $block) { | |
50 | if ($block != 'address') { | |
481a74f4 | 51 | $location[$block] = CRM_Core_BAO_Block::create($block, $params, $entity); |
6a488035 TO |
52 | } |
53 | else { | |
54 | $location[$block] = CRM_Core_BAO_Address::create($params, $fixAddress, $entity); | |
55 | } | |
56 | } | |
57 | ||
58 | if ($entity) { | |
59 | // this is a special case for adding values in location block table | |
be2fb01f | 60 | $entityElements = [ |
6a488035 TO |
61 | 'entity_table' => $params['entity_table'], |
62 | 'entity_id' => $params['entity_id'], | |
be2fb01f | 63 | ]; |
6a488035 TO |
64 | |
65 | $location['id'] = self::createLocBlock($location, $entityElements); | |
66 | } | |
67 | else { | |
68 | // when we come from a form which displays all the location elements (like the edit form or the inline block | |
69 | // elements, we can skip the below check. The below check adds quite a feq queries to an already overloaded | |
70 | // form | |
de6c59ca | 71 | if (empty($params['updateBlankLocInfo'])) { |
6a488035 TO |
72 | // make sure contact should have only one primary block, CRM-5051 |
73 | self::checkPrimaryBlocks(CRM_Utils_Array::value('contact_id', $params)); | |
74 | } | |
75 | } | |
76 | ||
77 | return $location; | |
78 | } | |
79 | ||
80 | /** | |
fe482240 | 81 | * Creates the entry in the civicrm_loc_block. |
ad37ac8e | 82 | * |
83 | * @param string $location | |
84 | * @param array $entityElements | |
85 | * | |
86 | * @return int | |
6a488035 | 87 | */ |
00be9182 | 88 | public static function createLocBlock(&$location, &$entityElements) { |
6a488035 | 89 | $locId = self::findExisting($entityElements); |
be2fb01f | 90 | $locBlock = []; |
6a488035 TO |
91 | |
92 | if ($locId) { | |
93 | $locBlock['id'] = $locId; | |
94 | } | |
95 | ||
be2fb01f | 96 | foreach ([ |
518fa0ee SL |
97 | 'phone', |
98 | 'email', | |
99 | 'im', | |
100 | 'address', | |
101 | ] as $loc) { | |
0d8afee2 CW |
102 | $locBlock["{$loc}_id"] = !empty($location["$loc"][0]) ? $location["$loc"][0]->id : NULL; |
103 | $locBlock["{$loc}_2_id"] = !empty($location["$loc"][1]) ? $location["$loc"][1]->id : NULL; | |
6a488035 TO |
104 | } |
105 | ||
106 | $countNull = 0; | |
107 | foreach ($locBlock as $key => $block) { | |
108 | if (empty($locBlock[$key])) { | |
109 | $locBlock[$key] = 'null'; | |
110 | $countNull++; | |
111 | } | |
112 | } | |
113 | ||
114 | if (count($locBlock) == $countNull) { | |
115 | // implies nothing is set. | |
116 | return NULL; | |
117 | } | |
118 | ||
119 | $locBlockInfo = self::addLocBlock($locBlock); | |
120 | return $locBlockInfo->id; | |
121 | } | |
122 | ||
123 | /** | |
fe482240 | 124 | * Takes an entity array and finds the existing location block. |
ad37ac8e | 125 | * |
126 | * @param array $entityElements | |
127 | * | |
128 | * @return int | |
6a488035 | 129 | */ |
00be9182 | 130 | public static function findExisting($entityElements) { |
353ffa53 | 131 | $eid = $entityElements['entity_id']; |
6a488035 | 132 | $etable = $entityElements['entity_table']; |
353ffa53 | 133 | $query = " |
6a488035 TO |
134 | SELECT e.loc_block_id as locId |
135 | FROM {$etable} e | |
136 | WHERE e.id = %1"; | |
137 | ||
be2fb01f | 138 | $params = [1 => [$eid, 'Integer']]; |
6a488035 TO |
139 | $dao = CRM_Core_DAO::executeQuery($query, $params); |
140 | while ($dao->fetch()) { | |
141 | $locBlockId = $dao->locId; | |
142 | } | |
143 | return $locBlockId; | |
144 | } | |
145 | ||
146 | /** | |
fe482240 | 147 | * Takes an associative array and adds location block. |
6a488035 | 148 | * |
6a0b768e TO |
149 | * @param array $params |
150 | * (reference ) an assoc array of name/value pairs. | |
6a488035 | 151 | * |
ad37ac8e | 152 | * @return CRM_Core_BAO_locBlock |
153 | * Object on success, null otherwise | |
6a488035 | 154 | */ |
00be9182 | 155 | public static function addLocBlock(&$params) { |
6a488035 TO |
156 | $locBlock = new CRM_Core_DAO_LocBlock(); |
157 | ||
158 | $locBlock->copyValues($params); | |
159 | ||
160 | return $locBlock->save(); | |
161 | } | |
162 | ||
163 | /** | |
fe482240 | 164 | * Delete the Location Block. |
6a488035 | 165 | * |
6a0b768e TO |
166 | * @param int $locBlockId |
167 | * Id of the Location Block. | |
6a488035 TO |
168 | */ |
169 | public static function deleteLocBlock($locBlockId) { | |
170 | if (!$locBlockId) { | |
171 | return; | |
172 | } | |
173 | ||
174 | $locBlock = new CRM_Core_DAO_LocBlock(); | |
175 | $locBlock->id = $locBlockId; | |
176 | ||
177 | $locBlock->find(TRUE); | |
178 | ||
179 | //resolve conflict of having same ids for multiple blocks | |
be2fb01f | 180 | $store = [ |
6a488035 TO |
181 | 'IM_1' => $locBlock->im_id, |
182 | 'IM_2' => $locBlock->im_2_id, | |
183 | 'Email_1' => $locBlock->email_id, | |
184 | 'Email_2' => $locBlock->email_2_id, | |
185 | 'Phone_1' => $locBlock->phone_id, | |
186 | 'Phone_2' => $locBlock->phone_2_id, | |
187 | 'Address_1' => $locBlock->address_id, | |
188 | 'Address_2' => $locBlock->address_2_id, | |
be2fb01f | 189 | ]; |
6a488035 TO |
190 | $locBlock->delete(); |
191 | foreach ($store as $daoName => $id) { | |
192 | if ($id) { | |
4d5c2eb5 | 193 | $daoName = 'CRM_Core_DAO_' . substr($daoName, 0, -2); |
194 | $dao = new $daoName(); | |
6a488035 TO |
195 | $dao->id = $id; |
196 | $dao->find(TRUE); | |
197 | $dao->delete(); | |
6a488035 TO |
198 | } |
199 | } | |
200 | } | |
201 | ||
202 | /** | |
fe482240 | 203 | * Check if there is data to create the object. |
6a488035 | 204 | * |
6a0b768e TO |
205 | * @param array $params |
206 | * (reference ) an assoc array of name/value pairs. | |
6a488035 | 207 | * |
acb1052e | 208 | * @return bool |
6a488035 | 209 | */ |
00be9182 | 210 | public static function dataExists(&$params) { |
6a488035 TO |
211 | // return if no data present |
212 | $dataExists = FALSE; | |
213 | foreach (self::$blocks as $block) { | |
214 | if (array_key_exists($block, $params)) { | |
215 | $dataExists = TRUE; | |
216 | break; | |
217 | } | |
218 | } | |
219 | ||
220 | return $dataExists; | |
221 | } | |
222 | ||
223 | /** | |
ad37ac8e | 224 | * Get values. |
225 | * | |
226 | * @param array $entityBlock | |
fd31fa4c EM |
227 | * @param bool $microformat |
228 | * | |
a6c01b45 CW |
229 | * @return array |
230 | * array of objects(CRM_Core_BAO_Location) | |
6a488035 | 231 | */ |
00be9182 | 232 | public static function &getValues($entityBlock, $microformat = FALSE) { |
6a488035 TO |
233 | if (empty($entityBlock)) { |
234 | return NULL; | |
235 | } | |
be2fb01f CW |
236 | $blocks = []; |
237 | $name_map = [ | |
6a488035 TO |
238 | 'im' => 'IM', |
239 | 'openid' => 'OpenID', | |
be2fb01f CW |
240 | ]; |
241 | $blocks = []; | |
6a488035 TO |
242 | //get all the blocks for this contact |
243 | foreach (self::$blocks as $block) { | |
244 | if (array_key_exists($block, $name_map)) { | |
245 | $name = $name_map[$block]; | |
246 | } | |
247 | else { | |
248 | $name = ucfirst($block); | |
249 | } | |
4d5c2eb5 | 250 | $baoString = 'CRM_Core_BAO_' . $name; |
c490a46a | 251 | $blocks[$block] = $baoString::getValues($entityBlock, $microformat); |
6a488035 TO |
252 | } |
253 | return $blocks; | |
254 | } | |
255 | ||
256 | /** | |
fe482240 | 257 | * Delete all the block associated with the location. |
6a488035 | 258 | * |
6a0b768e TO |
259 | * @param int $contactId |
260 | * Contact id. | |
261 | * @param int $locationTypeId | |
262 | * Id of the location to delete. | |
6a488035 | 263 | */ |
00be9182 | 264 | public static function deleteLocationBlocks($contactId, $locationTypeId) { |
6a488035 TO |
265 | // ensure that contactId has a value |
266 | if (empty($contactId) || | |
267 | !CRM_Utils_Rule::positiveInteger($contactId) | |
268 | ) { | |
269 | CRM_Core_Error::fatal(); | |
270 | } | |
271 | ||
272 | if (empty($locationTypeId) || | |
273 | !CRM_Utils_Rule::positiveInteger($locationTypeId) | |
274 | ) { | |
275 | // so we only delete the blocks which DO NOT have a location type Id | |
276 | // CRM-3581 | |
277 | $locationTypeId = 'null'; | |
278 | } | |
279 | ||
be2fb01f | 280 | static $blocks = ['Address', 'Phone', 'IM', 'OpenID', 'Email']; |
6a488035 | 281 | |
be2fb01f | 282 | $params = ['contact_id' => $contactId, 'location_type_id' => $locationTypeId]; |
6a488035 TO |
283 | foreach ($blocks as $name) { |
284 | CRM_Core_BAO_Block::blockDelete($name, $params); | |
285 | } | |
286 | } | |
287 | ||
c490a46a CW |
288 | /** |
289 | * Copy or update location block. | |
6a488035 | 290 | * |
6a0b768e TO |
291 | * @param int $locBlockId |
292 | * Location block id. | |
293 | * @param int $updateLocBlockId | |
294 | * Update location block id. | |
b5c2afd0 | 295 | * |
a6c01b45 CW |
296 | * @return int |
297 | * newly created/updated location block id. | |
b5c2afd0 | 298 | */ |
00be9182 | 299 | public static function copyLocBlock($locBlockId, $updateLocBlockId = NULL) { |
3fec1adc | 300 | CRM_Core_Error::deprecatedFunctionWarning('unused function which will be removed'); |
6a488035 | 301 | //get the location info. |
be2fb01f CW |
302 | $defaults = $updateValues = []; |
303 | $locBlock = ['id' => $locBlockId]; | |
6a488035 TO |
304 | CRM_Core_DAO::commonRetrieve('CRM_Core_DAO_LocBlock', $locBlock, $defaults); |
305 | ||
306 | if ($updateLocBlockId) { | |
307 | //get the location info for update. | |
be2fb01f | 308 | $copyLocationParams = ['id' => $updateLocBlockId]; |
6a488035 TO |
309 | CRM_Core_DAO::commonRetrieve('CRM_Core_DAO_LocBlock', $copyLocationParams, $updateValues); |
310 | foreach ($updateValues as $key => $value) { | |
311 | if ($key != 'id') { | |
312 | $copyLocationParams[$key] = 'null'; | |
313 | } | |
314 | } | |
315 | } | |
316 | ||
317 | //copy all location blocks (email, phone, address, etc) | |
318 | foreach ($defaults as $key => $value) { | |
319 | if ($key != 'id') { | |
353ffa53 TO |
320 | $tbl = explode("_", $key); |
321 | $name = ucfirst($tbl[0]); | |
6a488035 TO |
322 | $updateParams = NULL; |
323 | if ($updateId = CRM_Utils_Array::value($key, $updateValues)) { | |
be2fb01f | 324 | $updateParams = ['id' => $updateId]; |
6a488035 TO |
325 | } |
326 | ||
be2fb01f | 327 | $copy = CRM_Core_DAO::copyGeneric('CRM_Core_DAO_' . $name, ['id' => $value], $updateParams); |
6a488035 TO |
328 | $copyLocationParams[$key] = $copy->id; |
329 | } | |
330 | } | |
331 | ||
3fec1adc | 332 | $copyLocation = CRM_Core_DAO::copyGeneric('CRM_Core_DAO_LocBlock', |
be2fb01f | 333 | ['id' => $locBlock['id']], |
6a488035 TO |
334 | $copyLocationParams |
335 | ); | |
336 | return $copyLocation->id; | |
337 | } | |
338 | ||
339 | /** | |
ad37ac8e | 340 | * Make sure contact should have only one primary block, CRM-5051. |
6a488035 | 341 | * |
6a0b768e TO |
342 | * @param int $contactId |
343 | * Contact id. | |
6a488035 | 344 | */ |
00be9182 | 345 | public static function checkPrimaryBlocks($contactId) { |
6a488035 TO |
346 | if (!$contactId) { |
347 | return; | |
348 | } | |
349 | ||
350 | // get the loc block ids. | |
be2fb01f CW |
351 | $primaryLocBlockIds = CRM_Contact_BAO_Contact::getLocBlockIds($contactId, ['is_primary' => 1]); |
352 | $nonPrimaryBlockIds = CRM_Contact_BAO_Contact::getLocBlockIds($contactId, ['is_primary' => 0]); | |
6a488035 | 353 | |
be2fb01f | 354 | foreach ([ |
518fa0ee SL |
355 | 'Email', |
356 | 'IM', | |
357 | 'Phone', | |
358 | 'Address', | |
359 | 'OpenID', | |
360 | ] as $block) { | |
6a488035 TO |
361 | $name = strtolower($block); |
362 | if (array_key_exists($name, $primaryLocBlockIds) && | |
363 | !CRM_Utils_System::isNull($primaryLocBlockIds[$name]) | |
364 | ) { | |
365 | if (count($primaryLocBlockIds[$name]) > 1) { | |
366 | // keep only single block as primary. | |
367 | $primaryId = array_pop($primaryLocBlockIds[$name]); | |
368 | $resetIds = "(" . implode(',', $primaryLocBlockIds[$name]) . ")"; | |
369 | // reset all primary except one. | |
370 | CRM_Core_DAO::executeQuery("UPDATE civicrm_$name SET is_primary = 0 WHERE id IN $resetIds"); | |
371 | } | |
372 | } | |
373 | elseif (array_key_exists($name, $nonPrimaryBlockIds) && | |
374 | !CRM_Utils_System::isNull($nonPrimaryBlockIds[$name]) | |
375 | ) { | |
376 | // data exists and no primary block - make one primary. | |
377 | CRM_Core_DAO::setFieldValue("CRM_Core_DAO_" . $block, | |
378 | array_pop($nonPrimaryBlockIds[$name]), 'is_primary', 1 | |
379 | ); | |
380 | } | |
381 | } | |
382 | } | |
1d07e7ab CW |
383 | |
384 | /** | |
ad37ac8e | 385 | * Get chain select values (whatever that means!). |
386 | * | |
1d07e7ab CW |
387 | * @param mixed $values |
388 | * @param string $valueType | |
389 | * @param bool $flatten | |
390 | * | |
391 | * @return array | |
392 | */ | |
00be9182 | 393 | public static function getChainSelectValues($values, $valueType, $flatten = FALSE) { |
1d07e7ab | 394 | if (!$values) { |
be2fb01f | 395 | return []; |
1d07e7ab | 396 | } |
bc999cd1 | 397 | $values = array_filter((array) $values); |
be2fb01f | 398 | $elements = []; |
1d07e7ab CW |
399 | $list = &$elements; |
400 | $method = $valueType == 'country' ? 'stateProvinceForCountry' : 'countyForState'; | |
401 | foreach ($values as $val) { | |
402 | $result = CRM_Core_PseudoConstant::$method($val); | |
403 | ||
404 | // Format for quickform | |
405 | if ($flatten) { | |
406 | // Option-groups for multiple categories | |
407 | if ($result && count($values) > 1) { | |
408 | $elements["crm_optgroup_$val"] = CRM_Core_PseudoConstant::$valueType($val, FALSE); | |
409 | } | |
410 | $elements += $result; | |
411 | } | |
412 | ||
413 | // Format for js | |
414 | else { | |
353ffa53 | 415 | // Option-groups for multiple categories |
1d07e7ab | 416 | if ($result && count($values) > 1) { |
be2fb01f | 417 | $elements[] = [ |
1d07e7ab | 418 | 'value' => CRM_Core_PseudoConstant::$valueType($val, FALSE), |
be2fb01f CW |
419 | 'children' => [], |
420 | ]; | |
353ffa53 | 421 | $list = &$elements[count($elements) - 1]['children']; |
1d07e7ab CW |
422 | } |
423 | foreach ($result as $id => $name) { | |
be2fb01f | 424 | $list[] = [ |
1d07e7ab CW |
425 | 'value' => $name, |
426 | 'key' => $id, | |
be2fb01f | 427 | ]; |
1d07e7ab CW |
428 | } |
429 | } | |
430 | } | |
431 | return $elements; | |
432 | } | |
96025800 | 433 | |
6a488035 | 434 | } |