Merge pull request #15810 from eileenmcnaughton/mem_fix
[civicrm-core.git] / tools / scripts / solr / createSolrXML.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This code is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
12 /**
13 * Create a xml file for a set of contact ID's in a format digestible
14 * by Solr
15 */
16
17 require_once '../../civicrm.config.php';
18 require_once 'CRM/Core/Config.php';
19
20 define('CHUNK_SIZE', 128);
21
22 /**
23 * Split a large array of contactIDs into more manageable smaller chunks
24 * @param $contactIDs
25 * @return array
26 */
27 function &splitContactIDs(&$contactIDs) {
28 // contactIDs could be a real large array, so we split it up into
29 // smaller chunks and then general xml for each chunk
30 $chunks = [];
31 $current = 0;
32 $chunks[$current] = [];
33 $count = 0;
34
35 foreach ($contactIDs as $cid) {
36 $chunks[$current][] = $cid;
37 $count++;
38
39 if ($count == CHUNK_SIZE) {
40 $current++;
41 $chunks[$current] = [];
42 $count = 0;
43 }
44 }
45
46 if (empty($chunks[$current])) {
47 unset($chunks[$current]);
48 }
49
50 return $chunks;
51 }
52
53 /**
54 * Given an array of values, generate the XML in the Solr format
55 * @param $values
56 * @return string
57 */
58 function &generateSolrXML($values) {
59 $result = "<add>\n";
60 foreach ($values as $cid => $tokens) {
61 if (empty($tokens)) {
62 continue;
63 }
64
65 $result .= <<<EOT
66 <doc>
67 <field name="id">$cid</field>\n
68 EOT;
69
70 foreach ($tokens as $t) {
71 $result .= <<<EOT
72 <field name="$t[0]">$t[1]</field>\n
73 EOT;
74 }
75
76 $result .= " </doc>\n";
77 }
78 $result .= "</add>\n";
79
80
81 return $result;
82 }
83
84 /**
85 * Given a set of contact IDs get the values
86 * @param $contactIDs
87 * @param $values
88 * @return array
89 */
90 function getValues(&$contactIDs, &$values) {
91 $values = [];
92
93 foreach ($contactIDs as $cid) {
94 $values[$cid] = [];
95 }
96
97 getContactInfo($contactIDs, $values);
98 getLocationInfo($contactIDs, $values);
99
100 return $values;
101 }
102
103 /**
104 * @param $contactIDs
105 * @param $values
106 * @param $tableName
107 * @param $fields
108 * @param $whereField
109 * @param null $additionalWhereCond
110 */
111 function getTableInfo(&$contactIDs, &$values, $tableName, &$fields, $whereField, $additionalWhereCond = NULL) {
112 $selectString = implode(',', array_keys($fields));
113 $idString = implode(',', $contactIDs);
114
115 $sql = "
116 SELECT $selectString, $whereField as contact_id
117 FROM $tableName
118 WHERE $whereField IN ( $idString )
119 ";
120
121 if ($additionalWhereCond) {
122 $sql .= " AND $additionalWhereCond";
123 }
124
125 $dao = CRM_Core_DAO::executeQuery($sql);
126 while ($dao->fetch()) {
127 foreach ($fields as $fld => $name) {
128 if (empty($dao->$fld)) {
129 continue;
130 }
131 if (!$name) {
132 $name = $fld;
133 }
134 $values[$dao->contact_id][] = [$name, $dao->$fld];
135 }
136 }
137 }
138
139 /**
140 * @param $contactIDs
141 * @param $values
142 */
143 function getContactInfo(&$contactIDs, &$values) {
144 $fields = [
145 'sort_name' => NULL,
146 'display_name' => NULL,
147 'contact_type' => NULL,
148 'legal_identifier' => NULL,
149 'external_identifier' => NULL,
150 'source' => 'contact_source',
151 ];
152 getTableInfo($contactIDs, $values, 'civicrm_contact', $fields, 'id');
153
154 $fields = [
155 'first_name' => NULL,
156 'last_name' => NULL,
157 'middle_name' => NULL,
158 'job_title' => NULL,
159 ];
160 getTableInfo($contactIDs, $values, 'civicrm_individual', $fields, 'contact_id');
161
162 $fields = ['household_name' => NULL];
163 getTableInfo($contactIDs, $values, 'civicrm_household', $fields, 'contact_id');
164
165 $fields = [
166 'organization_name' => NULL,
167 'legal_name' => NULL,
168 'sic_code' => NULL,
169 ];
170 getTableInfo($contactIDs, $values, 'civicrm_organization', $fields, 'contact_id');
171
172 $fields = [
173 'note' => 'note_body',
174 'subject' => 'note_subject',
175 ];
176 getTableInfo($contactIDs, $values, 'civicrm_note', $fields, 'entity_id', "entity_table = 'civicrm_contact'");
177 }
178
179 /**
180 * @param $contactIDs
181 * @param $values
182 */
183 function getLocationInfo(&$contactIDs, &$values) {
184 $ids = implode(',', $contactIDs);
185
186 $sql = "
187 SELECT
188 l.entity_id as contact_id, l.name as location_name,
189 a.street_address, a.supplemental_address_1, a.supplemental_address_2,
190 a.supplemental_address_3,
191 a.city, a.postal_code,
192 co.name as county, s.name as state, c.name as country,
193 e.email, p.phone, i.name as im
194 FROM
195 civicrm_location l
196 LEFT JOIN civicrm_address a ON a.location_id = l.id
197 LEFT JOIN civicrm_email e ON e.location_id = l.id
198 LEFT JOIN civicrm_phone p ON p.location_id = l.id
199 LEFT JOIN civicrm_im i ON i.location_id = l.id
200 LEFT JOIN civicrm_state_province s ON a.state_province_id = s.id
201 LEFT JOIN civicrm_country c ON a.country_id = c.id
202 LEFT JOIN civicrm_county co ON a.county_id = co.id
203 WHERE l.entity_table = 'civicrm_contact'
204 AND l.entity_id IN ( $ids )
205 ";
206
207 $fields = [
208 'location_name',
209 'street_address',
210 'supplemental_address_1',
211 'supplemental_address_2',
212 'supplemental_address_3',
213 'city',
214 'postal_code',
215 'county',
216 'state',
217 'country',
218 'email',
219 'phone',
220 'im',
221 ];
222 $dao = CRM_Core_DAO::executeQuery($sql);
223 while ($dao->fetch()) {
224 foreach ($fields as $fld) {
225 if (empty($dao->$fld)) {
226 continue;
227 }
228 $values[$dao->contact_id][] = [$fld, $dao->$fld];
229 }
230 }
231 }
232
233 /**
234 * @param $contactIDs
235 */
236 function run(&$contactIDs) {
237 $chunks = &splitContactIDs($contactIDs);
238
239 foreach ($chunks as $chunk) {
240 $values = [];
241 getValues($chunk, $values);
242 $xml = &generateSolrXML($values);
243 echo $xml;
244 }
245 }
246
247 $config = CRM_Core_Config::singleton();
248 $config->userFramework = 'Soap';
249 $config->userFrameworkClass = 'CRM_Utils_System_Soap';
250 $config->userHookClass = 'CRM_Utils_Hook_Soap';
251
252 $sql = <<<EOT
253 SELECT id
254 FROM civicrm_contact
255 EOT;
256 $dao = CRM_Core_DAO::executeQuery($sql);
257
258 $contactIDs = [];
259 while ($dao->fetch()) {
260 $contactIDs[] = $dao->id;
261 }
262
263 run($contactIDs);
264