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