fix version in header
[civicrm-core.git] / tools / scripts / solr / createSolrJSON.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 Solr
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 */
40 function &splitContactIDs(&$contactIDs) {
41 // contactIDs could be a real large array, so we split it up into
42 // smaller chunks and then general xml for each chunk
43 $chunks = array();
44 $current = 0;
45 $chunks[$current] = array();
46 $count = 0;
47
48 foreach ($contactIDs as $cid) {
49 $chunks[$current][] = $cid;
50 $count++;
51
52 if ($count == CHUNK_SIZE) {
53 $current++;
54 $chunks[$current] = array();
55 $count = 0;
56 }
57 }
58
59 if (empty($chunks[$current])) {
60 unset($chunks[$current]);
61 }
62
63 return $chunks;
64 }
65
66 /**
67 * Given an array of values, generate the JSON in the Solr format
68 */
69 function &generateSolrJSON($values) {
70 $result = "[";
71 foreach ($values as $cid => $tokens) {
72 if (empty($tokens)) {
73 continue;
74 }
75
76 $result .= "\n {\n \"contact_id\" : \"$cid\",";
77
78 foreach ($tokens as $n => $v) {
79 if (is_array($v)) {
80 $str = array();
81 foreach ($v as $el) {
82 $el = escapeJsonString($el);
83 $str[] = "\"$el\"";
84 }
85 $string = implode(",", $str);
86 $result .= "\n \"{$n}\" : [$string],";
87 }
88 else {
89 $v = escapeJsonString($v);
90 $result .= "\n \"{$n}\" : \"{$v}\",";
91 }
92 }
93
94 // remove the last comma
95 $result = rtrim($result, ",");
96
97 $result .= "\n },";
98 }
99 // remove the last comma
100 $result = rtrim($result, ",");
101
102 $result .= "\n]\n";
103
104
105 return $result;
106 }
107
108 /**
109 * @param $value
110 *
111 * @return mixed
112 */
113 function escapeJsonString($value) {
114 $escapers = array("\\", "/", "\"", "\n", "\r", "\t", "\x08", "\x0c");
115 $replacements = array("\\\\", "\\/", "\\\"", "\\n", "\\r", "\\t", "\\f", "\\b");
116 return str_replace($escapers, $replacements, $value);
117 }
118
119 /**
120 * Given a set of contact IDs get the values
121 */
122 function getValues(&$contactIDs, &$values) {
123 $values = array();
124
125 foreach ($contactIDs as $cid) {
126 $values[$cid] = array();
127 }
128
129 getContactInfo($contactIDs, $values);
130 getAddressInfo($contactIDs, $values);
131 getPhoneInfo($contactIDs, $values);
132 getEmailInfo($contactIDs, $values);
133 getNoteInfo($contactIDs, $values);
134
135 return $values;
136 }
137
138 /**
139 * @param $contactIDs
140 * @param $values
141 * @param $tableName
142 * @param $fields
143 * @param $whereField
144 * @param null $additionalWhereCond
145 */
146 function getTableInfo(&$contactIDs, &$values, $tableName, &$fields, $whereField, $additionalWhereCond = NULL) {
147 $selectString = implode(',', array_keys($fields));
148 $idString = implode(',', $contactIDs);
149
150 $sql = "
151 SELECT $selectString, $whereField as contact_id
152 FROM $tableName
153 WHERE $whereField IN ( $idString )
154 ";
155
156 if ($additionalWhereCond) {
157 $sql .= " AND $additionalWhereCond";
158 }
159
160 $dao = &CRM_Core_DAO::executeQuery($sql);
161 while ($dao->fetch()) {
162 foreach ($fields as $fld => $name) {
163 $name = $name ? $name : $fld;
164 appendValue($values, $dao->contact_id, $name, $dao->$fld);
165 }
166 }
167 }
168
169 /**
170 * @param $contactIDs
171 * @param $values
172 */
173 function getContactInfo(&$contactIDs, &$values) {
174 $fields = array('sort_name' => NULL,
175 'display_name' => NULL,
176 'contact_type' => NULL,
177 'legal_identifier' => NULL,
178 'external_identifier' => NULL,
179 'first_name' => NULL,
180 'last_name' => NULL,
181 'middle_name' => NULL,
182 'household_name' => NULL,
183 'organization_name' => NULL,
184 'legal_name' => NULL,
185 'job_title' => NULL,
186 );
187 getTableInfo($contactIDs, $values, 'civicrm_contact', $fields, 'id');
188 }
189
190 /**
191 * @param $contactIDs
192 * @param $values
193 */
194 function getNoteInfo(&$contactIDs, &$values) {
195 $ids = implode(',', $contactIDs);
196
197 $sql = "
198 SELECT
199 entity_id as contact_id,
200 note as note, subject as subject
201 FROM civicrm_note
202 WHERE entity_id IN ( $ids )
203 AND entity_table = 'civicrm_contact'
204 ";
205
206 $dao = &CRM_Core_DAO::executeQuery($sql);
207 while ($dao->fetch()) {
208 $note = empty($dao->subject) ? '' : "{$dao->subject}: ";
209 $note .= empty($dao->note) ? '' : $dao->note;
210
211 appendValue($values, $dao->contact_id, 'note', $note);
212 }
213 }
214
215 /**
216 * @param $contactIDs
217 * @param $values
218 */
219 function getPhoneInfo(&$contactIDs, &$values) {
220 $ids = implode(',', $contactIDs);
221
222 $sql = "
223 SELECT
224 c.id as contact_id,
225 l.name as location_type,
226 p.phone as phone,
227 v.label as phone_type
228 FROM civicrm_contact c
229 INNER JOIN civicrm_phone p ON p.contact_id = c.id
230 LEFT JOIN civicrm_location_type l ON p.location_type_id = l.id
231 LEFT JOIN civicrm_option_group g ON g.name = 'phone_type'
232 LEFT JOIN civicrm_option_value v ON v.option_group_id = g.id AND p.phone_type_id = v.value
233 WHERE c.id IN ( $ids )
234 AND p.phone IS NOT NULL
235 ";
236
237 $dao = &CRM_Core_DAO::executeQuery($sql);
238 while ($dao->fetch()) {
239 $phone = '';
240
241 if (!empty($dao->location_type)) {
242 $phone = "{$dao->location_type}: ";
243 }
244
245 $phone .= $dao->phone;
246
247 if (!empty($dao->phone_type)) {
248 $phone .= " ({$dao->phone_type})";
249 }
250
251 appendValue($values, $dao->contact_id, 'phone', $phone);
252 }
253 }
254
255 /**
256 * @param $contactIDs
257 * @param $values
258 */
259 function getEmailInfo(&$contactIDs, &$values) {
260 $ids = implode(',', $contactIDs);
261
262 $sql = "
263 SELECT
264 c.id as contact_id,
265 l.name as location_type,
266 e.email as email
267 FROM civicrm_contact c
268 INNER JOIN civicrm_email e ON e.contact_id = c.id
269 LEFT JOIN civicrm_location_type l ON e.location_type_id = l.id
270 WHERE c.id IN ( $ids )
271 AND e.email IS NOT NULL
272 ";
273
274 $dao = &CRM_Core_DAO::executeQuery($sql);
275 while ($dao->fetch()) {
276 $email = '';
277
278 if (!empty($dao->location_type)) {
279 $email = "{$dao->location_type}: ";
280 }
281
282 $email .= $dao->email;
283 appendValue($values, $dao->contact_id, 'email', $email);
284 }
285 }
286
287 /**
288 * @param $contactIDs
289 * @param $values
290 */
291 function getAddressInfo(&$contactIDs, &$values) {
292 $ids = implode(',', $contactIDs);
293
294 $sql = "
295 SELECT c.id as contact_id, l.name as location_type,
296 a.street_address, a.supplemental_address_1, a.supplemental_address_2,
297 a.city, a.postal_code,
298 s.name as state, co.name as country
299 FROM civicrm_contact c
300 INNER JOIN civicrm_address a ON a.contact_id = c.id
301 LEFT JOIN civicrm_location_type l ON a.location_type_id = l.id
302 LEFT JOIN civicrm_state_province s ON a.state_province_id = s.id
303 LEFT JOIN civicrm_country co ON a.country_id = co.id
304 WHERE c.id IN ( $ids )
305 ";
306
307 $fields = array('location_type', 'street_address', 'supplemental_address_1',
308 'supplemental_address_2', 'city', 'postal_code',
309 'state', 'country',
310 );
311 $dao = &CRM_Core_DAO::executeQuery($sql);
312 while ($dao->fetch()) {
313 $address = '';
314 foreach ($fields as $fld) {
315 if (empty($dao->$fld)) {
316 continue;
317 }
318
319 $address .= ($fld == 'location_type') ? "{$dao->$fld}: " : " {$dao->$fld},";
320 appendValue($values, $dao->contact_id, $fld, $dao->$fld);
321 }
322
323 if (!empty($address)) {
324 $address = rtrim($address, ",");
325 appendValue($values, $dao->contact_id, 'address', $address);
326 }
327 }
328 }
329
330 /**
331 * @param $values
332 * @param $contactID
333 * @param $name
334 * @param $value
335 */
336 function appendValue(&$values, $contactID, $name, $value) {
337 if (empty($value)) {
338 return;
339 }
340
341 if (!isset($values[$contactID][$name])) {
342 $values[$contactID][$name] = $value;
343 }
344 else {
345 if (!is_array($values[$contactID][$name])) {
346 $save = $values[$contactID][$name];
347 $values[$contactID][$name] = array();
348 $values[$contactID][$name][] = $save;
349 }
350 $values[$contactID][$name][] = $value;
351 }
352 }
353
354 /**
355 * @param $contactIDs
356 */
357 function run(&$contactIDs) {
358 $chunks = &splitContactIDs($contactIDs);
359
360 foreach ($chunks as $chunk) {
361 $values = array();
362 getValues($chunk, $values);
363 $xml = &generateSolrJSON($values);
364 echo $xml;
365 }
366 }
367
368 $config = &CRM_Core_Config::singleton();
369 $config->userFramework = 'Soap';
370 $config->userFrameworkClass = 'CRM_Utils_System_Soap';
371 $config->userHookClass = 'CRM_Utils_Hook_Soap';
372
373 $sql = <<<EOT
374 SELECT id
375 FROM civicrm_contact
376 EOT;
377 $dao = &CRM_Core_DAO::executeQuery($sql);
378
379
380 $contactIDs = array();
381 while ($dao->fetch()) {
382 $contactIDs[] = $dao->id;
383 }
384
385 run($contactIDs);
386