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