remove trailing whitespaces
[civicrm-core.git] / CRM / Core / BAO / Location.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.3 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
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
31 * @copyright CiviCRM LLC (c) 2004-2013
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 /**
47 * Function to create various elements of location block
48 *
49 * @param array $params (reference ) an assoc array of name/value pairs
50 * @param boolean $fixAddress true if you need to fix (format) address values
51 * before inserting in db
52 *
53 * @return array $location
54 * @access public
55 * @static
56 */
57 static function create(&$params, $fixAddress = TRUE, $entity = NULL) {
58 $location = array();
59 if (!self::dataExists($params)) {
60 return $location;
61 }
62
63 // create location blocks.
64 foreach (self::$blocks as $block) {
65 if ($block != 'address') {
66 eval('$location[$block] = CRM_Core_BAO_Block::create( $block, $params, $entity );');
67 }
68 else {
69 $location[$block] = CRM_Core_BAO_Address::create($params, $fixAddress, $entity);
70 }
71 }
72
73 if ($entity) {
74 // this is a special case for adding values in location block table
75 $entityElements = array(
76 'entity_table' => $params['entity_table'],
77 'entity_id' => $params['entity_id'],
78 );
79
80 $location['id'] = self::createLocBlock($location, $entityElements);
81 }
82 else {
83 // when we come from a form which displays all the location elements (like the edit form or the inline block
84 // elements, we can skip the below check. The below check adds quite a feq queries to an already overloaded
85 // form
86 if (!CRM_Utils_Array::value('updateBlankLocInfo', $params, FALSE)) {
87 // make sure contact should have only one primary block, CRM-5051
88 self::checkPrimaryBlocks(CRM_Utils_Array::value('contact_id', $params));
89 }
90 }
91
92 return $location;
93 }
94
95 /**
96 * Creates the entry in the civicrm_loc_block
97 *
98 */
99 static function createLocBlock(&$location, &$entityElements) {
100 $locId = self::findExisting($entityElements);
101 $locBlock = array();
102
103 if ($locId) {
104 $locBlock['id'] = $locId;
105 }
106
107 foreach (array(
108 'phone', 'email', 'im', 'address') as $loc) {
109 $locBlock["{$loc}_id"] = CRM_Utils_Array::value(0, $location["$loc"]) ? $location["$loc"][0]->id : NULL;
110 $locBlock["{$loc}_2_id"] = CRM_Utils_Array::value(1, $location["$loc"]) ? $location["$loc"][1]->id : NULL;
111 }
112
113 $countNull = 0;
114 foreach ($locBlock as $key => $block) {
115 if (empty($locBlock[$key])) {
116 $locBlock[$key] = 'null';
117 $countNull++;
118 }
119 }
120
121 if (count($locBlock) == $countNull) {
122 // implies nothing is set.
123 return NULL;
124 }
125
126 $locBlockInfo = self::addLocBlock($locBlock);
127 return $locBlockInfo->id;
128 }
129
130 /**
131 * takes an entity array and finds the existing location block
132 * @access public
133 * @static
134 */
135 static function findExisting($entityElements) {
136 $eid = $entityElements['entity_id'];
137 $etable = $entityElements['entity_table'];
138 $query = "
139SELECT e.loc_block_id as locId
140FROM {$etable} e
141WHERE e.id = %1";
142
143 $params = array(1 => array($eid, 'Integer'));
144 $dao = CRM_Core_DAO::executeQuery($query, $params);
145 while ($dao->fetch()) {
146 $locBlockId = $dao->locId;
147 }
148 return $locBlockId;
149 }
150
151 /**
152 * takes an associative array and adds location block
153 *
154 * @param array $params (reference ) an assoc array of name/value pairs
155 *
156 * @return object CRM_Core_BAO_locBlock object on success, null otherwise
157 * @access public
158 * @static
159 */
160 static function addLocBlock(&$params) {
161 $locBlock = new CRM_Core_DAO_LocBlock();
162
163 $locBlock->copyValues($params);
164
165 return $locBlock->save();
166 }
167
168 /**
169 * This function deletes the Location Block
170 *
171 * @param int $locBlockId id of the Location Block
172 *
173 * @return void
174 * @access public
175 * @static
176 */
177 public static function deleteLocBlock($locBlockId) {
178 if (!$locBlockId) {
179 return;
180 }
181
182 $locBlock = new CRM_Core_DAO_LocBlock();
183 $locBlock->id = $locBlockId;
184
185 $locBlock->find(TRUE);
186
187 //resolve conflict of having same ids for multiple blocks
188 $store = array(
189 'IM_1' => $locBlock->im_id,
190 'IM_2' => $locBlock->im_2_id,
191 'Email_1' => $locBlock->email_id,
192 'Email_2' => $locBlock->email_2_id,
193 'Phone_1' => $locBlock->phone_id,
194 'Phone_2' => $locBlock->phone_2_id,
195 'Address_1' => $locBlock->address_id,
196 'Address_2' => $locBlock->address_2_id,
197 );
198 $locBlock->delete();
199 foreach ($store as $daoName => $id) {
200 if ($id) {
201 $daoName = substr($daoName, 0, -2);
202 eval('$dao = new CRM_Core_DAO_' . $daoName . '( );');
203 $dao->id = $id;
204 $dao->find(TRUE);
205 $dao->delete();
206 $dao->free();
207 }
208 }
209 }
210
211 /**
212 * Check if there is data to create the object
213 *
214 * @param array $params (reference ) an assoc array of name/value pairs
215 *
216 * @return boolean
217 * @access public
218 * @static
219 */
220 static function dataExists(&$params) {
221 // return if no data present
222 $dataExists = FALSE;
223 foreach (self::$blocks as $block) {
224 if (array_key_exists($block, $params)) {
225 $dataExists = TRUE;
226 break;
227 }
228 }
229
230 return $dataExists;
231 }
232
233 /**
234 * Given the list of params in the params array, fetch the object
235 * and store the values in the values array
236 *
237 * @param array $params input parameters to find object
238 * @param array $values output values of the object
239 *
240 * @return array array of objects(CRM_Core_BAO_Location)
241 * @access public
242 * @static
243 */
244 static function &getValues($entityBlock, $microformat = FALSE) {
245 if (empty($entityBlock)) {
246 return NULL;
247 }
248
249 $name_map = array(
250 'im' => 'IM',
251 'openid' => 'OpenID',
252 );
e52506b0 253 $blocks = array();
6a488035
TO
254 //get all the blocks for this contact
255 foreach (self::$blocks as $block) {
256 if (array_key_exists($block, $name_map)) {
257 $name = $name_map[$block];
258 }
259 else {
260 $name = ucfirst($block);
261 }
e52506b0 262 $baoString = 'CRM_Core_BAO_' . $name ;
263 $blocks[$block] = $baoString::getValues( $entityBlock, $microformat );
6a488035
TO
264 }
265 return $blocks;
266 }
267
268 /**
269 * Delete all the block associated with the location
270 *
271 * @param int $contactId contact id
272 * @param int $locationTypeId id of the location to delete
273 *
274 * @return void
275 * @access public
276 * @static
277 */
278 static function deleteLocationBlocks($contactId, $locationTypeId) {
279 // ensure that contactId has a value
280 if (empty($contactId) ||
281 !CRM_Utils_Rule::positiveInteger($contactId)
282 ) {
283 CRM_Core_Error::fatal();
284 }
285
286 if (empty($locationTypeId) ||
287 !CRM_Utils_Rule::positiveInteger($locationTypeId)
288 ) {
289 // so we only delete the blocks which DO NOT have a location type Id
290 // CRM-3581
291 $locationTypeId = 'null';
292 }
293
294 static $blocks = array('Address', 'Phone', 'IM', 'OpenID', 'Email');
295
296 $params = array('contact_id' => $contactId, 'location_type_id' => $locationTypeId);
297 foreach ($blocks as $name) {
298 CRM_Core_BAO_Block::blockDelete($name, $params);
299 }
300 }
301
302 /* Function to copy or update location block.
303 *
304 * @param int $locBlockId location block id.
305 * @param int $updateLocBlockId update location block id
306 * @return int newly created/updated location block id.
307 */
308 static function copyLocBlock($locBlockId, $updateLocBlockId = NULL) {
309 //get the location info.
310 $defaults = $updateValues = array();
311 $locBlock = array('id' => $locBlockId);
312 CRM_Core_DAO::commonRetrieve('CRM_Core_DAO_LocBlock', $locBlock, $defaults);
313
314 if ($updateLocBlockId) {
315 //get the location info for update.
316 $copyLocationParams = array('id' => $updateLocBlockId);
317 CRM_Core_DAO::commonRetrieve('CRM_Core_DAO_LocBlock', $copyLocationParams, $updateValues);
318 foreach ($updateValues as $key => $value) {
319 if ($key != 'id') {
320 $copyLocationParams[$key] = 'null';
321 }
322 }
323 }
324
325 //copy all location blocks (email, phone, address, etc)
326 foreach ($defaults as $key => $value) {
327 if ($key != 'id') {
328 $tbl = explode("_", $key);
329 $name = ucfirst($tbl[0]);
330 $updateParams = NULL;
331 if ($updateId = CRM_Utils_Array::value($key, $updateValues)) {
332 $updateParams = array('id' => $updateId);
333 }
334
335 $copy = CRM_Core_DAO::copyGeneric('CRM_Core_DAO_' . $name, array('id' => $value), $updateParams);
336 $copyLocationParams[$key] = $copy->id;
337 }
338 }
339
340 $copyLocation = &CRM_Core_DAO::copyGeneric('CRM_Core_DAO_LocBlock',
341 array('id' => $locBlock['id']),
342 $copyLocationParams
343 );
344 return $copyLocation->id;
345 }
346
347 /**
348 * If contact has data for any location block, make sure
349 * contact should have only one primary block, CRM-5051
350 *
351 * @param int $contactId - contact id
352 *
353 * @access public
354 * @static
355 */
356 static function checkPrimaryBlocks($contactId) {
357 if (!$contactId) {
358 return;
359 }
360
361 // get the loc block ids.
362 $primaryLocBlockIds = CRM_Contact_BAO_Contact::getLocBlockIds($contactId, array('is_primary' => 1));
363 $nonPrimaryBlockIds = CRM_Contact_BAO_Contact::getLocBlockIds($contactId, array('is_primary' => 0));
364
365 foreach (array(
366 'Email', 'IM', 'Phone', 'Address', 'OpenID') as $block) {
367 $name = strtolower($block);
368 if (array_key_exists($name, $primaryLocBlockIds) &&
369 !CRM_Utils_System::isNull($primaryLocBlockIds[$name])
370 ) {
371 if (count($primaryLocBlockIds[$name]) > 1) {
372 // keep only single block as primary.
373 $primaryId = array_pop($primaryLocBlockIds[$name]);
374 $resetIds = "(" . implode(',', $primaryLocBlockIds[$name]) . ")";
375 // reset all primary except one.
376 CRM_Core_DAO::executeQuery("UPDATE civicrm_$name SET is_primary = 0 WHERE id IN $resetIds");
377 }
378 }
379 elseif (array_key_exists($name, $nonPrimaryBlockIds) &&
380 !CRM_Utils_System::isNull($nonPrimaryBlockIds[$name])
381 ) {
382 // data exists and no primary block - make one primary.
383 CRM_Core_DAO::setFieldValue("CRM_Core_DAO_" . $block,
384 array_pop($nonPrimaryBlockIds[$name]), 'is_primary', 1
385 );
386 }
387 }
388 }
389}
390