Merge pull request #8347 from eileenmcnaughton/tidy-up
[civicrm-core.git] / CRM / Contact / Form / Task / Label.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
7e9e8871 4 | CiviCRM version 4.7 |
6a488035 5 +--------------------------------------------------------------------+
fa938177 6 | Copyright CiviCRM LLC (c) 2004-2016 |
6a488035
TO
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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 *
30 * @package CRM
fa938177 31 * @copyright CiviCRM LLC (c) 2004-2016
6a488035
TO
32 */
33
34/**
00252851 35 * This class helps to print the labels for contacts.
6a488035
TO
36 */
37class CRM_Contact_Form_Task_Label extends CRM_Contact_Form_Task {
38
39 /**
fe482240 40 * Build all the data structures needed to build the form.
6a488035 41 */
00be9182 42 public function preProcess() {
6a488035
TO
43 $this->set('contactIds', $this->_contactIds);
44 parent::preProcess();
45 }
46
47 /**
fe482240 48 * Build the form object.
6a488035 49 */
00be9182 50 public function buildQuickForm() {
6a488035
TO
51 CRM_Utils_System::setTitle(ts('Make Mailing Labels'));
52
53 //add select for label
54 $label = CRM_Core_BAO_LabelFormat::getList(TRUE);
55
56 $this->add('select', 'label_name', ts('Select Label'), array('' => ts('- select label -')) + $label, TRUE);
57
6a488035
TO
58 // add select for Location Type
59 $this->addElement('select', 'location_type_id', ts('Select Location'),
60 array(
af9b09df 61 '' => ts('Primary'),
353ffa53 62 ) + CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id'), TRUE
6a488035
TO
63 );
64
65 // checkbox for SKIP contacts with Do Not Mail privacy option
66 $this->addElement('checkbox', 'do_not_mail', ts('Do not print labels for contacts with "Do Not Mail" privacy option checked'));
67
68 $this->add('checkbox', 'merge_same_address', ts('Merge labels for contacts with the same address'), NULL);
69 $this->add('checkbox', 'merge_same_household', ts('Merge labels for contacts belonging to the same household'), NULL);
70
85d25c8f
DG
71 $this->addButtons(array(
72 array(
73 'type' => 'submit',
74 'name' => ts('Make Mailing Labels'),
75 'isDefault' => TRUE,
76 ),
77 array(
78 'type' => 'cancel',
79 'name' => ts('Done'),
80 ),
81 ));
6a488035
TO
82 }
83
84 /**
c490a46a 85 * Set default values for the form.
6a488035 86 *
a6c01b45
CW
87 * @return array
88 * array of default values
6a488035 89 */
00be9182 90 public function setDefaultValues() {
6a488035
TO
91 $defaults = array();
92 $format = CRM_Core_BAO_LabelFormat::getDefaultValues();
93 $defaults['label_name'] = CRM_Utils_Array::value('name', $format);
94 $defaults['do_not_mail'] = 1;
95
96 return $defaults;
97 }
98
99 /**
fe482240 100 * Process the form after the input has been submitted and validated.
6a488035
TO
101 */
102 public function postProcess() {
353ffa53
TO
103 $fv = $this->controller->exportValues($this->_name);
104 $config = CRM_Core_Config::singleton();
6a488035
TO
105 $locName = NULL;
106 //get the address format sequence from the config file
aaffa79f 107 $mailingFormat = Civi::settings()->get('mailing_format');
6a488035
TO
108
109 $sequence = CRM_Utils_Address::sequence($mailingFormat);
110
111 foreach ($sequence as $v) {
112 $address[$v] = 1;
113 }
114
115 if (array_key_exists('postal_code', $address)) {
116 $address['postal_code_suffix'] = 1;
117 }
118
119 //build the returnproperties
3131433e 120 $returnProperties = array('display_name' => 1, 'contact_type' => 1, 'prefix_id' => 1);
aaffa79f 121 $mailingFormat = Civi::settings()->get('mailing_format');
6a488035
TO
122
123 $mailingFormatProperties = array();
124 if ($mailingFormat) {
bdd49e38 125 $mailingFormatProperties = CRM_Utils_Token::getReturnProperties($mailingFormat);
6a488035
TO
126 $returnProperties = array_merge($returnProperties, $mailingFormatProperties);
127 }
128 //we should not consider addressee for data exists, CRM-6025
129 if (array_key_exists('addressee', $mailingFormatProperties)) {
130 unset($mailingFormatProperties['addressee']);
131 }
132
133 $customFormatProperties = array();
134 if (stristr($mailingFormat, 'custom_')) {
135 foreach ($mailingFormatProperties as $token => $true) {
136 if (substr($token, 0, 7) == 'custom_') {
a7488080 137 if (empty($customFormatProperties[$token])) {
6a488035
TO
138 $customFormatProperties[$token] = $mailingFormatProperties[$token];
139 }
140 }
141 }
142 }
143
144 if (!empty($customFormatProperties)) {
145 $returnProperties = array_merge($returnProperties, $customFormatProperties);
146 }
147
148 if (isset($fv['merge_same_address'])) {
149 // we need first name/last name for summarising to avoid spillage
150 $returnProperties['first_name'] = 1;
151 $returnProperties['last_name'] = 1;
152 }
153
57884c26
DJ
154 $individualFormat = FALSE;
155
156 /*
157 * CRM-8338: replace ids of household members with the id of their household
158 * so we can merge labels by household.
159 */
160 if (isset($fv['merge_same_household'])) {
161 $this->mergeContactIdsByHousehold();
162 $individualFormat = TRUE;
163 }
164
6a488035
TO
165 //get the contacts information
166 $params = array();
a7488080 167 if (!empty($fv['location_type_id'])) {
353ffa53
TO
168 $locType = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id');
169 $locName = $locType[$fv['location_type_id']];
170 $location = array('location' => array("{$locName}" => $address));
6a488035 171 $returnProperties = array_merge($returnProperties, $location);
81b22b66 172 $params[] = array('location_type', '=', array(1 => $fv['location_type_id']), 0, 0);
6a488035
TO
173 }
174 else {
175 $returnProperties = array_merge($returnProperties, $address);
176 }
177
178 $rows = array();
179
180 foreach ($this->_contactIds as $key => $contactID) {
181 $params[] = array(
182 CRM_Core_Form::CB_PREFIX . $contactID,
353ffa53
TO
183 '=',
184 1,
185 0,
186 0,
6a488035
TO
187 );
188 }
189
190 // fix for CRM-2651
a7488080 191 if (!empty($fv['do_not_mail'])) {
6a488035
TO
192 $params[] = array('do_not_mail', '=', 0, 0, 0);
193 }
194 // fix for CRM-2613
195 $params[] = array('is_deceased', '=', 0, 0, 0);
196
197 $custom = array();
198 foreach ($returnProperties as $name => $dontCare) {
199 $cfID = CRM_Core_BAO_CustomField::getKeyID($name);
200 if ($cfID) {
201 $custom[] = $cfID;
202 }
203 }
204
205 //get the total number of contacts to fetch from database.
206 $numberofContacts = count($this->_contactIds);
353ffa53
TO
207 $query = new CRM_Contact_BAO_Query($params, $returnProperties);
208 $details = $query->apiQuery($params, $returnProperties, NULL, NULL, 0, $numberofContacts);
6a488035
TO
209
210 $messageToken = CRM_Utils_Token::getTokens($mailingFormat);
211
212 // also get all token values
213 CRM_Utils_Hook::tokenValues($details[0],
214 $this->_contactIds,
215 NULL,
216 $messageToken,
217 'CRM_Contact_Form_Task_Label'
218 );
219
220 $tokens = array();
221 CRM_Utils_Hook::tokens($tokens);
222 $tokenFields = array();
223 foreach ($tokens as $category => $catTokens) {
224 foreach ($catTokens as $token => $tokenName) {
225 $tokenFields[] = $token;
226 }
227 }
228
229 foreach ($this->_contactIds as $value) {
230 foreach ($custom as $cfID) {
231 if (isset($details[0][$value]["custom_{$cfID}"])) {
8cee0c70 232 $details[0][$value]["custom_{$cfID}"] = CRM_Core_BAO_CustomField::displayValue($details[0][$value]["custom_{$cfID}"], $cfID);
6a488035
TO
233 }
234 }
235 $contact = CRM_Utils_Array::value($value, $details['0']);
236
237 if (is_a($contact, 'CRM_Core_Error')) {
238 return NULL;
239 }
240
241 // we need to remove all the "_id"
242 unset($contact['contact_id']);
243
8cc574cf 244 if ($locName && !empty($contact[$locName])) {
6a488035
TO
245 // If location type is not primary, $contact contains
246 // one more array as "$contact[$locName] = array( values... )"
247
8bdfc216 248 if (!self::tokenIsFound($contact, $mailingFormatProperties, $tokenFields)) {
6a488035
TO
249 continue;
250 }
251
ceebbde9 252 $contact = array_merge($contact, $contact[$locName]);
6a488035
TO
253 unset($contact[$locName]);
254
a7488080 255 if (!empty($contact['county_id'])) {
6a488035
TO
256 unset($contact['county_id']);
257 }
258
259 foreach ($contact as $field => $fieldValue) {
260 $rows[$value][$field] = $fieldValue;
261 }
262
263 $valuesothers = array();
264 $paramsothers = array('contact_id' => $value);
265 $valuesothers = CRM_Core_BAO_Location::getValues($paramsothers, $valuesothers);
a7488080 266 if (!empty($fv['location_type_id'])) {
6a488035 267 foreach ($valuesothers as $vals) {
353ffa53
TO
268 if (CRM_Utils_Array::value('location_type_id', $vals) ==
269 CRM_Utils_Array::value('location_type_id', $fv)
270 ) {
6a488035
TO
271 foreach ($vals as $k => $v) {
272 if (in_array($k, array(
353ffa53
TO
273 'email',
274 'phone',
275 'im',
af9b09df 276 'openid',
353ffa53 277 ))) {
6a488035
TO
278 if ($k == 'im') {
279 $rows[$value][$k] = $v['1']['name'];
280 }
281 else {
282 $rows[$value][$k] = $v['1'][$k];
283 }
284 $rows[$value][$k . '_id'] = $v['1']['id'];
285 }
286 }
287 }
288 }
289 }
290 }
291 else {
8bdfc216 292 if (!self::tokenIsFound($contact, $mailingFormatProperties, $tokenFields)) {
6a488035
TO
293 continue;
294 }
295
a7488080 296 if (!empty($contact['addressee_display'])) {
6a488035
TO
297 $contact['addressee_display'] = trim($contact['addressee_display']);
298 }
a7488080 299 if (!empty($contact['addressee'])) {
6a488035
TO
300 $contact['addressee'] = $contact['addressee_display'];
301 }
302
303 // now create the rows for generating mailing labels
304 foreach ($contact as $field => $fieldValue) {
305 $rows[$value][$field] = $fieldValue;
306 }
307 }
308 }
309
6a488035 310 if (isset($fv['merge_same_address'])) {
8bdfc216 311 CRM_Core_BAO_Address::mergeSameAddress($rows);
6a488035
TO
312 $individualFormat = TRUE;
313 }
6a488035
TO
314
315 // format the addresses according to CIVICRM_ADDRESS_FORMAT (CRM-1327)
316 foreach ($rows as $id => $row) {
317 if ($commMethods = CRM_Utils_Array::value('preferred_communication_method', $row)) {
353ffa53 318 $val = array_filter(explode(CRM_Core_DAO::VALUE_SEPARATOR, $commMethods));
e7e657f0 319 $comm = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
6a488035
TO
320 $temp = array();
321 foreach ($val as $vals) {
322 $temp[] = $comm[$vals];
323 }
324 $row['preferred_communication_method'] = implode(', ', $temp);
325 }
326 $row['id'] = $id;
327 $formatted = CRM_Utils_Address::format($row, 'mailing_format', FALSE, TRUE, $individualFormat, $tokenFields);
328
329 // CRM-2211: UFPDF doesn't have bidi support; use the PECL fribidi package to fix it.
330 // On Ubuntu (possibly Debian?) be aware of http://pecl.php.net/bugs/bug.php?id=12366
331 // Due to FriBidi peculiarities, this can't be called on
332 // a multi-line string, hence the explode+implode approach.
333 if (function_exists('fribidi_log2vis')) {
334 $lines = explode("\n", $formatted);
335 foreach ($lines as $i => $line) {
336 $lines[$i] = fribidi_log2vis($line, FRIBIDI_AUTO, FRIBIDI_CHARSET_UTF8);
337 }
338 $formatted = implode("\n", $lines);
339 }
340 $rows[$id] = array($formatted);
341 }
342
343 //call function to create labels
344 self::createLabel($rows, $fv['label_name']);
345 CRM_Utils_System::civiExit(1);
346 }
347
c91c5542 348 /**
fe482240 349 * Check for presence of tokens to be swapped out.
77b97be7 350 *
c91c5542 351 * @param array $contact
352 * @param array $mailingFormatProperties
353 * @param array $tokenFields
77b97be7
EM
354 *
355 * @return bool
c91c5542 356 */
8bdfc216 357 public static function tokenIsFound($contact, $mailingFormatProperties, $tokenFields) {
c91c5542 358 foreach (array_merge($mailingFormatProperties, array_fill_keys($tokenFields, 1)) as $key => $dontCare) {
8bdfc216 359 //we should not consider addressee for data exists, CRM-6025
353ffa53 360 if ($key != 'addressee' && !empty($contact[$key])) {
c91c5542 361 return TRUE;
362 }
363 }
364 return FALSE;
365 }
353ffa53 366
6a488035 367 /**
00252851 368 * Create labels (pdf).
6a488035 369 *
77c5b619 370 * @param array $contactRows
00252851 371 * Associated array of contact data.
77c5b619
TO
372 * @param string $format
373 * Format in which labels needs to be printed.
374 * @param string $fileName
375 * The name of the file to save the label in.
6a488035 376 */
00be9182 377 public function createLabel(&$contactRows, &$format, $fileName = 'MailingLabels_CiviCRM.pdf') {
6a488035
TO
378 $pdf = new CRM_Utils_PDF_Label($format, 'mm');
379 $pdf->Open();
380 $pdf->AddPage();
381
382 //build contact string that needs to be printed
383 $val = NULL;
384 foreach ($contactRows as $row => $value) {
385 foreach ($value as $k => $v) {
386 $val .= "$v\n";
387 }
388
389 $pdf->AddPdfLabel($val);
390 $val = '';
391 }
392 $pdf->Output($fileName, 'D');
393 }
394
6a488035 395}