Merge remote-tracking branch 'upstream/4.5' into 4.5-master-2015-01-26-14-28-00
[civicrm-core.git] / tools / scripts / solr / createSyncJSON.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
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. |
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 along with this program; if not, contact CiviCRM LLC |
21 | at info[AT]civicrm[DOT]org. If you have questions about the |
22 | GNU Affero General Public License or the licensing of CiviCRM, |
23 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
24 +--------------------------------------------------------------------+
25 */
26
27 /**
28 * Create a xml file for a set of contact ID's in a format digestible
29 * by our Sync scripts
30 */
31
32 require_once '../../../civicrm.settings.php';
33 require_once 'CRM/Core/Config.php';
34
35 define('CHUNK_SIZE', 128);
36
37 /**
38 * Split a large array of contactIDs into more manageable smaller chunks
39 * @param $contactIDs
40 * @return array
41 */
42 function &splitContactIDs(&$contactIDs) {
43 // contactIDs could be a real large array, so we split it up into
44 // smaller chunks and then general xml for each chunk
45 $chunks = array();
46 $current = 0;
47 $chunks[$current] = array();
48 $count = 0;
49
50 foreach ($contactIDs as $k => $v) {
51 $chunks[$current][$k] = $v;
52 $count++;
53
54 if ($count == CHUNK_SIZE) {
55 $current++;
56 $chunks[$current] = array();
57 $count = 0;
58 }
59 }
60
61 if (empty($chunks[$current])) {
62 unset($chunks[$current]);
63 }
64
65 return $chunks;
66 }
67
68 /**
69 * Given a set of contact IDs get the values
70 * @param $contactIDs
71 * @param $values
72 * @param $allContactIDs
73 * @param $addditionalContactIDs
74 * @return array
75 */
76 function getValues(&$contactIDs, &$values, &$allContactIDs, &$addditionalContactIDs) {
77 $values = array();
78
79 getContactInfo($contactIDs, $values);
80 getAddressInfo($contactIDs, $values);
81 getPhoneInfo($contactIDs, $values);
82 getEmailInfo($contactIDs, $values);
83 getNoteInfo($contactIDs, $values);
84
85 getRelationshipInfo($contactIDs, $values, $allContactIDs, $addditionalContactIDs);
86
87 getActivityInfo($contactIDs, $values, $allContactIDs, $addditionalContactIDs);
88
89 // got to do groups, tags
90
91 // got to do meta data
92
93 return $values;
94 }
95
96 /**
97 * @param $contactIDs
98 * @param $values
99 * @param $tableName
100 * @param $fields
101 * @param $whereField
102 * @param null $additionalWhereCond
103 * @param bool $flat
104 */
105 function getTableInfo(&$contactIDs, &$values, $tableName, &$fields,
106 $whereField, $additionalWhereCond = NULL,
107 $flat = FALSE
108 ) {
109 $selectString = implode(',', array_keys($fields));
110 $idString = implode(',', $contactIDs);
111
112 $sql = "
113 SELECT $selectString, $whereField as contact_id
114 FROM $tableName
115 WHERE $whereField IN ( $idString )
116 ";
117
118 if ($additionalWhereCond) {
119 $sql .= " AND $additionalWhereCond";
120 }
121
122 $dao = &CRM_Core_DAO::executeQuery($sql);
123 while ($dao->fetch()) {
124 $contact = array();
125 foreach ($fields as $fld => $name) {
126 $name = $name ? $name : $fld;
127 if (empty($dao->$fld)) {
128 $contact[$name] = NULL;
129 }
130 else {
131 $contact[$name] = $dao->$fld;
132 }
133 }
134 appendValue($values, $dao->contact_id, 'contact', $contact, $flat);
135 }
136 $dao->free();
137 }
138
139 /**
140 * @param $contactIDs
141 * @param $values
142 */
143 function getContactInfo(&$contactIDs, &$values) {
144 $fields = array('id' => NULL,
145 'sort_name' => NULL,
146 'display_name' => NULL,
147 'contact_type' => NULL,
148 'legal_identifier' => NULL,
149 'external_identifier' => NULL,
150 'first_name' => NULL,
151 'last_name' => NULL,
152 'middle_name' => NULL,
153 'household_name' => NULL,
154 'organization_name' => NULL,
155 'legal_name' => NULL,
156 'job_title' => NULL,
157 );
158 getTableInfo($contactIDs, $values, 'civicrm_contact', $fields, 'id', NULL, TRUE);
159 }
160
161 /**
162 * @param $contactIDs
163 * @param $values
164 */
165 function getNoteInfo(&$contactIDs, &$values) {
166 $ids = implode(',', $contactIDs);
167
168 $sql = "
169 SELECT
170 id,
171 entity_id as contact_id,
172 note as note, subject as subject
173 FROM civicrm_note
174 WHERE entity_id IN ( $ids )
175 AND entity_table = 'civicrm_contact'
176 ";
177
178 $dao = &CRM_Core_DAO::executeQuery($sql);
179 while ($dao->fetch()) {
180 $note = array('id' => $dao->id,
181 'contact_id' => $dao->contact_id,
182 'subject' => empty($dao->subject) ? NULL : $dao->subject,
183 'note' => empty($dao->note) ? NULL : $dao->note,
184 );
185
186 appendValue($values, $dao->id, 'note', $note);
187 }
188 $dao->free();
189 }
190
191 /**
192 * @param $contactIDs
193 * @param $values
194 */
195 function getPhoneInfo(&$contactIDs, &$values) {
196 $ids = implode(',', $contactIDs);
197
198 $sql = "
199 SELECT
200 p.id as id,
201 c.id as contact_id,
202 l.name as location_type,
203 p.phone as phone,
204 v.label as phone_type
205 FROM civicrm_contact c
206 INNER JOIN civicrm_phone p ON p.contact_id = c.id
207 LEFT JOIN civicrm_location_type l ON p.location_type_id = l.id
208 LEFT JOIN civicrm_option_group g ON g.name = 'phone_type'
209 LEFT JOIN civicrm_option_value v ON v.option_group_id = g.id AND p.phone_type_id = v.value
210 WHERE c.id IN ( $ids )
211 AND p.phone IS NOT NULL
212 ";
213
214 $dao = &CRM_Core_DAO::executeQuery($sql);
215 while ($dao->fetch()) {
216 $phone = array('id' => $dao->id,
217 'contact_id' => $dao->contact_id,
218 'location_type' => empty($dao->location_type) ? NULL : $dao->location_type,
219 'phone' => $dao->phone,
220 'phone_type' => empty($dao->phone_type) ? NULL : $dao->phone_type,
221 );
222
223 appendValue($values, $dao->id, 'phone', $phone);
224 }
225 $dao->free();
226 }
227
228 /**
229 * @param $contactIDs
230 * @param $values
231 */
232 function getEmailInfo(&$contactIDs, &$values) {
233 $ids = implode(',', $contactIDs);
234
235 $sql = "
236 SELECT
237 e.id as id,
238 c.id as contact_id,
239 l.name as location_type,
240 e.email as email
241 FROM civicrm_contact c
242 INNER JOIN civicrm_email e ON e.contact_id = c.id
243 LEFT JOIN civicrm_location_type l ON e.location_type_id = l.id
244 WHERE c.id IN ( $ids )
245 AND e.email IS NOT NULL
246 ";
247
248 $dao = &CRM_Core_DAO::executeQuery($sql);
249 while ($dao->fetch()) {
250 $email = array('id' => $dao->id,
251 'contact_id' => $dao->contact_id,
252 'location_type' => empty($dao->location_type) ? NULL : $dao->location_type,
253 'email' => $dao->email,
254 );
255 appendValue($values, $dao->id, 'email', $email);
256 }
257 $dao->free();
258 }
259
260 /**
261 * @param $contactIDs
262 * @param $values
263 */
264 function getAddressInfo(&$contactIDs, &$values) {
265 $ids = implode(',', $contactIDs);
266
267 $sql = "
268 SELECT a.id as id,
269 c.id as contact_id, l.name as location_type,
270 a.street_address, a.supplemental_address_1, a.supplemental_address_2,
271 a.city, a.postal_code,
272 s.name as state, co.name as country
273 FROM civicrm_contact c
274 INNER JOIN civicrm_address a ON a.contact_id = c.id
275 LEFT JOIN civicrm_location_type l ON a.location_type_id = l.id
276 LEFT JOIN civicrm_state_province s ON a.state_province_id = s.id
277 LEFT JOIN civicrm_country co ON a.country_id = co.id
278 WHERE c.id IN ( $ids )
279 ";
280
281 $fields = array('id', 'contact_id',
282 'location_type', 'street_address', 'supplemental_address_1',
283 'supplemental_address_2', 'city', 'postal_code',
284 'state', 'country',
285 );
286 $dao = &CRM_Core_DAO::executeQuery($sql);
287 while ($dao->fetch()) {
288 $address = array();
289 foreach ($fields as $fld) {
290 if (empty($dao->$fld)) {
291 $address[$fld] = NULL;
292 }
293 else {
294 $address[$fld] = $dao->$fld;
295 }
296 }
297 appendValue($values, $dao->id, 'address', $address);
298 }
299 $dao->free();
300 }
301
302 /**
303 * @param $contactIDs
304 * @param $values
305 * @param $allContactIDs
306 * @param $additionalContacts
307 */
308 function getRelationshipInfo(&$contactIDs, &$values, &$allContactIDs, &$additionalContacts) {
309 // handle relationships only once
310 static $_relationshipsHandled = array();
311
312 $ids = implode(',', $contactIDs);
313
314 $sql = "(
315 SELECT r.*
316 FROM civicrm_relationship r
317 WHERE r.contact_id_a IN ( $ids )
318 ) UNION (
319 SELECT r.*
320 FROM civicrm_relationship r
321 WHERE r.contact_id_b IN ( $ids )
322 )
323 ";
324
325 $relationshipFields = getDBFields('CRM_Contact_DAO_Relationship');
326 $fields = array_keys($relationshipFields);
327 $dao = &CRM_Core_DAO::executeQuery($sql);
328 while ($dao->fetch()) {
329 if (isset($_relationshipsHandled[$dao->id])) {
330 continue;
331 }
332 $_relationshipsHandled[$dao->id] = $dao->id;
333
334 $relationship = array();
335 foreach ($fields as $fld) {
336 if (empty($dao->$fld)) {
337 $relationship[$fld] = NULL;
338 }
339 else {
340 $relationship[$fld] = $dao->$fld;
341 }
342 }
343 appendValue($values, $dao->id, 'relationship', $relationship);
344
345 addAdditionalContacts(array($dao->contact_id_a,
346 $dao->contact_id_b,
347 ),
348 $allContactIDs, $additionalContacts
349 );
350 }
351 $dao->free();
352 }
353
354 /**
355 * @param $contactIDs
356 * @param $values
357 * @param $allContactIDs
358 * @param $additionalContacts
359 */
360 function getActivityInfo(&$contactIDs, &$values, &$allContactIDs, &$additionalContacts) {
361 static $_activitiesHandled = array();
362
363 $ids = implode(',', $contactIDs);
364
365 $sql = "(
366 SELECT a.*
367 FROM civicrm_activity a
368 INNER JOIN civicrm_activity_assignment aa ON aa.activity_id = a.id
369 WHERE aa.assignee_contact_id IN ( $ids )
370 AND ( a.activity_type_id != 3 AND a.activity_type_id != 20 )
371 ) UNION (
372 SELECT a.*
373 FROM civicrm_activity a
374 INNER JOIN civicrm_activity_target at ON at.activity_id = a.id
375 WHERE at.target_contact_id IN ( $ids )
376 AND ( a.activity_type_id != 3 AND a.activity_type_id != 20 )
377 )
378 ";
379
380 $activityFields = &getDBFields('CRM_Activity_DAO_Activity');
381 $fields = array_keys($activityFields);
382
383 $activityIDs = array();
384 $dao = &CRM_Core_DAO::executeQuery($sql);
385 while ($dao->fetch()) {
386 if (isset($_activitiesHandled[$dao->id])) {
387 continue;
388 }
389 $_activitiesHandled[$dao->id] = $dao->id;
390 $activityIDs[] = $dao->id;
391
392 $activity = array();
393 foreach ($fields as $fld) {
394 if (empty($dao->$fld)) {
395 $activity[$fld] = NULL;
396 }
397 else {
398 $activity[$fld] = $dao->$fld;
399 }
400 }
401
402 appendValue($values, $dao->id, 'activity', $activity);
403 addAdditionalContacts(array($dao->source_contact_id),
404 $allContactIDs, $additionalContacts
405 );
406 }
407 $dao->free();
408
409 if (empty($activityIDs)) {
410 return;
411 }
412
413 $activityIDString = implode(",", $activityIDs);
414
415 // now get all assignee contact ids and target contact ids for this activity
416 $sql = "SELECT * FROM civicrm_activity_assignment WHERE activity_id IN ($activityIDString)";
417 $aaDAO = &CRM_Core_DAO::executeQuery($sql);
418 $activityContacts = array();
419 while ($aaDAO->fetch()) {
420 $activityAssignee = array('id' => $aaDAO->id,
421 'assignee_contact_id' => $aaDAO->assignee_contact_id,
422 'activity_id' => $aaDAO->activity_id,
423 );
424 appendValue($values, $aaDAO->id, 'activity_assignment', $activityAssignee);
425 $activityContacts[] = $aaDAO->assignee_contact_id;
426 }
427 $aaDAO->free();
428
429 $sql = "SELECT * FROM civicrm_activity_target WHERE activity_id IN ($activityIDString)";
430 $atDAO = &CRM_Core_DAO::executeQuery($sql);
431 while ($atDAO->fetch()) {
432 $activityTarget = array('id' => $atDAO->id,
433 'target_contact_id' => $atDAO->target_contact_id,
434 'activity_id' => $atDAO->activity_id,
435 );
436 appendValue($values, $atDAO->id, 'activity_target', $activityTarget);
437 $activityContacts[] = $atDAO->target_contact_id;
438 }
439 $atDAO->free();
440
441 addAdditionalContacts($activityContacts, $allContactIDs, $additionalContacts);
442 }
443
444 /**
445 * @param $values
446 * @param $id
447 * @param $name
448 * @param $value
449 * @param bool $ignored
450 */
451 function appendValue(&$values, $id, $name, $value, $ignored = FALSE) {
452 if (empty($value)) {
453 return;
454 }
455
456 if (!isset($values[$name])) {
457 $values[$name] = array();
458 $values[$name][] = array_keys($value);
459 }
460 $values[$name][] = array_values($value);
461 }
462
463 /**
464 * @param string $daoName
465 *
466 * @return mixed
467 */
468 function getDBFields($daoName) {
469 static $_fieldsRetrieved = array();
470
471 if (!isset($_fieldsRetrieved[$daoName])) {
472 $_fieldsRetrieved[$daoName] = array();
473 $daoFile = str_replace('_',
474 DIRECTORY_SEPARATOR,
475 $daoName
476 ) . '.php';
477 include_once ($daoFile);
478
479 $daoFields = &$daoName::fields();
480 require_once 'CRM/Utils/Array.php';
481
482 foreach ($daoFields as $key => & $value) {
483 $_fieldsRetrieved[$daoName][$value['name']] = array('uniqueName' => $key,
484 'type' => $value['type'],
485 'title' => CRM_Utils_Array::value('title', $value, NULL),
486 );
487 }
488 }
489 return $_fieldsRetrieved[$daoName];
490 }
491
492 /**
493 * @param $contactIDs
494 * @param $allContactIDs
495 * @param $additionalContacts
496 */
497 function addAdditionalContacts($contactIDs, &$allContactIDs, &$additionalContacts) {
498 foreach ($contactIDs as $cid) {
499 if ($cid &&
500 !isset($allContactIDs[$cid]) &&
501 !isset($additionalContacts[$cid])
502 ) {
503 $additionalContacts[$cid] = $cid;
504 }
505 }
506 }
507
508 /**
509 * @param $values
510 * @param $contactIDs
511 * @param $allContactIDs
512 */
513 function run(&$values, &$contactIDs, &$allContactIDs) {
514 $chunks = &splitContactIDs($contactIDs);
515
516 $additionalContactIDs = array();
517
518 foreach ($chunks as $chunk) {
519 getValues($chunk, $values, $allContactIDs, $additionalContactIDs);
520 }
521
522 if (!empty($additionalContactIDs)) {
523 $allContactIDs = $allContactIDs + $additionalContactIDs;
524 run($values, $additionalContactIDs, $allContactIDs);
525 }
526 }
527
528 $config = &CRM_Core_Config::singleton();
529 $config->userFramework = 'Soap';
530 $config->userFrameworkClass = 'CRM_Utils_System_Soap';
531 $config->userHookClass = 'CRM_Utils_Hook_Soap';
532
533 $sql = "
534 SELECT id
535 FROM civicrm_contact
536 LIMIT 10
537 ";
538 $dao = &CRM_Core_DAO::executeQuery($sql);
539
540
541 $contactIDs = array();
542 while ($dao->fetch()) {
543 $contactIDs[$dao->id] = $dao->id;
544 }
545
546 $values = array();
547 run($values, $contactIDs, $contactIDs);
548
549 $json = json_encode($values);
550 echo $json;
551 // print_r( json_decode( $json ) );
552