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