Merge pull request #21965 from civicrm/5.43
[civicrm-core.git] / CRM / Core / BAO / Location.php
CommitLineData
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 */
21class 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 *
a6c01b45 38 * @return array
6a488035 39 */
531b6c9e 40 public static function create(&$params, $fixAddress = TRUE) {
be2fb01f 41 $location = [];
6a488035
TO
42 if (!self::dataExists($params)) {
43 return $location;
44 }
45
46 // create location blocks.
47 foreach (self::$blocks as $block) {
ae7397a3 48 if ($block !== 'address') {
531b6c9e 49 $location[$block] = CRM_Core_BAO_Block::create($block, $params);
6a488035 50 }
ae7397a3 51 elseif (is_array($params['address'] ?? NULL)) {
52 $location[$block] = CRM_Core_BAO_Address::legacyCreate($params, $fixAddress);
6a488035
TO
53 }
54 }
55
6a488035
TO
56 return $location;
57 }
58
59 /**
fe482240 60 * Creates the entry in the civicrm_loc_block.
ad37ac8e 61 *
41c9d147 62 * @param array $location
ad37ac8e 63 * @param array $entityElements
64 *
65 * @return int
6a488035 66 */
41c9d147 67 public static function createLocBlock($location, $entityElements) {
aa06ad4a 68 CRM_Core_Error::deprecatedFunctionWarning('Use LocBlock api');
6a488035 69 $locId = self::findExisting($entityElements);
be2fb01f 70 $locBlock = [];
6a488035
TO
71
72 if ($locId) {
73 $locBlock['id'] = $locId;
74 }
75
be2fb01f 76 foreach ([
518fa0ee
SL
77 'phone',
78 'email',
79 'im',
80 'address',
81 ] as $loc) {
0d8afee2
CW
82 $locBlock["{$loc}_id"] = !empty($location["$loc"][0]) ? $location["$loc"][0]->id : NULL;
83 $locBlock["{$loc}_2_id"] = !empty($location["$loc"][1]) ? $location["$loc"][1]->id : NULL;
6a488035
TO
84 }
85
86 $countNull = 0;
87 foreach ($locBlock as $key => $block) {
88 if (empty($locBlock[$key])) {
89 $locBlock[$key] = 'null';
90 $countNull++;
91 }
92 }
93
94 if (count($locBlock) == $countNull) {
95 // implies nothing is set.
96 return NULL;
97 }
98
41c9d147 99 return self::addLocBlock($locBlock)->id;
6a488035
TO
100 }
101
102 /**
fe482240 103 * Takes an entity array and finds the existing location block.
ad37ac8e 104 *
105 * @param array $entityElements
106 *
107 * @return int
6a488035 108 */
00be9182 109 public static function findExisting($entityElements) {
353ffa53 110 $eid = $entityElements['entity_id'];
6a488035 111 $etable = $entityElements['entity_table'];
353ffa53 112 $query = "
6a488035
TO
113SELECT e.loc_block_id as locId
114FROM {$etable} e
115WHERE e.id = %1";
116
be2fb01f 117 $params = [1 => [$eid, 'Integer']];
6a488035
TO
118 $dao = CRM_Core_DAO::executeQuery($query, $params);
119 while ($dao->fetch()) {
120 $locBlockId = $dao->locId;
121 }
122 return $locBlockId;
123 }
124
125 /**
fe482240 126 * Takes an associative array and adds location block.
6a488035 127 *
6a0b768e 128 * @param array $params
6a488035 129 *
41c9d147 130 * @return CRM_Core_DAO_LocBlock
ad37ac8e 131 * Object on success, null otherwise
6a488035 132 */
41c9d147 133 public static function addLocBlock($params) {
6a488035 134 $locBlock = new CRM_Core_DAO_LocBlock();
6a488035 135 $locBlock->copyValues($params);
531b6c9e 136 $locBlock->save();
137 return $locBlock;
6a488035
TO
138 }
139
140 /**
fe482240 141 * Delete the Location Block.
6a488035 142 *
6a0b768e
TO
143 * @param int $locBlockId
144 * Id of the Location Block.
6a488035
TO
145 */
146 public static function deleteLocBlock($locBlockId) {
147 if (!$locBlockId) {
148 return;
149 }
150
151 $locBlock = new CRM_Core_DAO_LocBlock();
152 $locBlock->id = $locBlockId;
153
154 $locBlock->find(TRUE);
155
156 //resolve conflict of having same ids for multiple blocks
be2fb01f 157 $store = [
6a488035
TO
158 'IM_1' => $locBlock->im_id,
159 'IM_2' => $locBlock->im_2_id,
160 'Email_1' => $locBlock->email_id,
161 'Email_2' => $locBlock->email_2_id,
162 'Phone_1' => $locBlock->phone_id,
163 'Phone_2' => $locBlock->phone_2_id,
164 'Address_1' => $locBlock->address_id,
165 'Address_2' => $locBlock->address_2_id,
be2fb01f 166 ];
6a488035
TO
167 $locBlock->delete();
168 foreach ($store as $daoName => $id) {
169 if ($id) {
4d5c2eb5 170 $daoName = 'CRM_Core_DAO_' . substr($daoName, 0, -2);
171 $dao = new $daoName();
6a488035
TO
172 $dao->id = $id;
173 $dao->find(TRUE);
174 $dao->delete();
6a488035
TO
175 }
176 }
177 }
178
179 /**
fe482240 180 * Check if there is data to create the object.
6a488035 181 *
6a0b768e
TO
182 * @param array $params
183 * (reference ) an assoc array of name/value pairs.
6a488035 184 *
acb1052e 185 * @return bool
6a488035 186 */
00be9182 187 public static function dataExists(&$params) {
6a488035
TO
188 // return if no data present
189 $dataExists = FALSE;
190 foreach (self::$blocks as $block) {
191 if (array_key_exists($block, $params)) {
192 $dataExists = TRUE;
193 break;
194 }
195 }
196
197 return $dataExists;
198 }
199
200 /**
ad37ac8e 201 * Get values.
202 *
203 * @param array $entityBlock
fd31fa4c
EM
204 * @param bool $microformat
205 *
d357f225 206 * @return CRM_Core_BAO_Location[]|NULL
6a488035 207 */
d357f225 208 public static function getValues($entityBlock, $microformat = FALSE) {
6a488035
TO
209 if (empty($entityBlock)) {
210 return NULL;
211 }
be2fb01f
CW
212 $blocks = [];
213 $name_map = [
6a488035
TO
214 'im' => 'IM',
215 'openid' => 'OpenID',
be2fb01f
CW
216 ];
217 $blocks = [];
6a488035
TO
218 //get all the blocks for this contact
219 foreach (self::$blocks as $block) {
220 if (array_key_exists($block, $name_map)) {
221 $name = $name_map[$block];
222 }
223 else {
224 $name = ucfirst($block);
225 }
4d5c2eb5 226 $baoString = 'CRM_Core_BAO_' . $name;
c490a46a 227 $blocks[$block] = $baoString::getValues($entityBlock, $microformat);
6a488035
TO
228 }
229 return $blocks;
230 }
231
232 /**
fe482240 233 * Delete all the block associated with the location.
6a488035 234 *
0a104499 235 * Note a universe search on 1 Oct 2020 found no calls to this function.
236 *
237 * @deprecated
238 *
6a0b768e
TO
239 * @param int $contactId
240 * Contact id.
241 * @param int $locationTypeId
242 * Id of the location to delete.
ac15829d 243 * @throws CRM_Core_Exception
6a488035 244 */
00be9182 245 public static function deleteLocationBlocks($contactId, $locationTypeId) {
0a104499 246 CRM_Core_Error::deprecatedFunctionWarning('Use v4 api');
6a488035
TO
247 // ensure that contactId has a value
248 if (empty($contactId) ||
249 !CRM_Utils_Rule::positiveInteger($contactId)
250 ) {
ac15829d 251 throw new CRM_Core_Exception('Incorrect contact id parameter passed to deleteLocationBlocks');
6a488035
TO
252 }
253
254 if (empty($locationTypeId) ||
255 !CRM_Utils_Rule::positiveInteger($locationTypeId)
256 ) {
257 // so we only delete the blocks which DO NOT have a location type Id
258 // CRM-3581
259 $locationTypeId = 'null';
260 }
261
be2fb01f 262 static $blocks = ['Address', 'Phone', 'IM', 'OpenID', 'Email'];
6a488035 263
be2fb01f 264 $params = ['contact_id' => $contactId, 'location_type_id' => $locationTypeId];
6a488035
TO
265 foreach ($blocks as $name) {
266 CRM_Core_BAO_Block::blockDelete($name, $params);
267 }
268 }
269
6a488035 270 /**
ad37ac8e 271 * Make sure contact should have only one primary block, CRM-5051.
6a488035 272 *
6a0b768e
TO
273 * @param int $contactId
274 * Contact id.
6a488035 275 */
00be9182 276 public static function checkPrimaryBlocks($contactId) {
6a488035
TO
277 if (!$contactId) {
278 return;
279 }
280
281 // get the loc block ids.
be2fb01f
CW
282 $primaryLocBlockIds = CRM_Contact_BAO_Contact::getLocBlockIds($contactId, ['is_primary' => 1]);
283 $nonPrimaryBlockIds = CRM_Contact_BAO_Contact::getLocBlockIds($contactId, ['is_primary' => 0]);
6a488035 284
be2fb01f 285 foreach ([
518fa0ee
SL
286 'Email',
287 'IM',
288 'Phone',
289 'Address',
290 'OpenID',
291 ] as $block) {
6a488035
TO
292 $name = strtolower($block);
293 if (array_key_exists($name, $primaryLocBlockIds) &&
294 !CRM_Utils_System::isNull($primaryLocBlockIds[$name])
295 ) {
296 if (count($primaryLocBlockIds[$name]) > 1) {
297 // keep only single block as primary.
298 $primaryId = array_pop($primaryLocBlockIds[$name]);
299 $resetIds = "(" . implode(',', $primaryLocBlockIds[$name]) . ")";
300 // reset all primary except one.
301 CRM_Core_DAO::executeQuery("UPDATE civicrm_$name SET is_primary = 0 WHERE id IN $resetIds");
302 }
303 }
304 elseif (array_key_exists($name, $nonPrimaryBlockIds) &&
305 !CRM_Utils_System::isNull($nonPrimaryBlockIds[$name])
306 ) {
307 // data exists and no primary block - make one primary.
308 CRM_Core_DAO::setFieldValue("CRM_Core_DAO_" . $block,
309 array_pop($nonPrimaryBlockIds[$name]), 'is_primary', 1
310 );
311 }
312 }
313 }
1d07e7ab
CW
314
315 /**
ad37ac8e 316 * Get chain select values (whatever that means!).
317 *
1d07e7ab
CW
318 * @param mixed $values
319 * @param string $valueType
320 * @param bool $flatten
321 *
322 * @return array
323 */
00be9182 324 public static function getChainSelectValues($values, $valueType, $flatten = FALSE) {
1d07e7ab 325 if (!$values) {
be2fb01f 326 return [];
1d07e7ab 327 }
bc999cd1 328 $values = array_filter((array) $values);
be2fb01f 329 $elements = [];
1d07e7ab
CW
330 $list = &$elements;
331 $method = $valueType == 'country' ? 'stateProvinceForCountry' : 'countyForState';
332 foreach ($values as $val) {
333 $result = CRM_Core_PseudoConstant::$method($val);
334
335 // Format for quickform
336 if ($flatten) {
337 // Option-groups for multiple categories
338 if ($result && count($values) > 1) {
339 $elements["crm_optgroup_$val"] = CRM_Core_PseudoConstant::$valueType($val, FALSE);
340 }
341 $elements += $result;
342 }
343
344 // Format for js
345 else {
353ffa53 346 // Option-groups for multiple categories
1d07e7ab 347 if ($result && count($values) > 1) {
be2fb01f 348 $elements[] = [
1d07e7ab 349 'value' => CRM_Core_PseudoConstant::$valueType($val, FALSE),
be2fb01f
CW
350 'children' => [],
351 ];
353ffa53 352 $list = &$elements[count($elements) - 1]['children'];
1d07e7ab
CW
353 }
354 foreach ($result as $id => $name) {
be2fb01f 355 $list[] = [
1d07e7ab
CW
356 'value' => $name,
357 'key' => $id,
be2fb01f 358 ];
1d07e7ab
CW
359 }
360 }
361 }
362 return $elements;
363 }
96025800 364
6a488035 365}