Merge pull request #15875 from civicrm/5.20
[civicrm-core.git] / CRM / Utils / PDF / Label.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work 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 * Class to print labels in Avery or custom formats
14 * functionality and smarts to the base PDF_Label.
15 *
16 * @package CRM
17 * @copyright CiviCRM LLC https://civicrm.org/licensing
18 */
19
20 /**
21 * Class CRM_Utils_PDF_Label
22 */
23 class CRM_Utils_PDF_Label extends TCPDF {
24
25 // make these properties public due to
26 // CRM-5880
27 /**
28 * Default label format values
29 * @var array
30 */
31 public $defaults;
32 /**
33 * Current label format values
34 * @var array
35 */
36 public $format;
37 /**
38 * Name of format
39 * @var string
40 */
41 public $formatName;
42 /**
43 * Left margin of labels
44 * @var float
45 */
46 public $marginLeft;
47 /**
48 * Top margin of labels
49 * @var float
50 */
51 public $marginTop;
52 /**
53 * Horizontal space between 2 labels
54 * @var float
55 */
56 public $xSpace;
57 /**
58 * Vertical space between 2 labels
59 * @var float
60 */
61 public $ySpace;
62 /**
63 * Number of labels horizontally
64 * @var float
65 */
66 public $xNumber;
67 /**
68 * Number of labels vertically
69 * @var float
70 */
71 public $yNumber;
72 /**
73 * Width of label
74 * @var float
75 */
76 public $width;
77 /**
78 * Height of label
79 * @var float
80 */
81 public $height;
82 /**
83 * Line Height of label - used in event code
84 * @var float
85 */
86 public $lineHeight = 0;
87 /**
88 * Space between text and left edge of label
89 * @var float
90 */
91 public $paddingLeft;
92 /**
93 * Space between text and top edge of label
94 * @var float
95 */
96 public $paddingTop;
97 /**
98 * Character size (in points)
99 * @var float
100 */
101 public $charSize;
102 /**
103 * Metric used for all PDF doc measurements
104 * @var string
105 */
106 public $metricDoc;
107 /**
108 * Name of the font
109 * @var string
110 */
111 public $fontName;
112 /**
113 * 'B' bold, 'I' italic, 'BI' bold+italic
114 * @var string
115 */
116 public $fontStyle;
117 /**
118 * Paper size name
119 * @var string
120 */
121 public $paperSize;
122 /**
123 * Paper orientation
124 * @var string
125 */
126 public $orientation;
127 /**
128 * Paper dimensions array (w, h)
129 * @var array
130 */
131 public $paper_dimensions;
132 /**
133 * Counter for positioning labels
134 * @var float
135 */
136 public $countX = 0;
137 /**
138 * Counter for positioning labels
139 * @var float
140 */
141 public $countY = 0;
142
143 /**
144 * Constructor.
145 *
146 * @param $format
147 * Either the name of a Label Format in the Option Value table.
148 * or an array of Label Format values.
149 * @param string|\Unit $unit Unit of measure for the PDF document
150 */
151 public function __construct($format, $unit = 'mm') {
152 if (is_array($format)) {
153 // Custom format
154 $tFormat = $format;
155 }
156 else {
157 // Saved format
158 $tFormat = CRM_Core_BAO_LabelFormat::getByName($format);
159 }
160
161 $this->LabelSetFormat($tFormat, $unit);
162 parent::__construct($this->orientation, $this->metricDoc, $this->paper_dimensions);
163 $this->generatorMethod = NULL;
164 $this->SetFont($this->fontName, $this->fontStyle);
165 $this->SetFontSize($this->charSize);
166 $this->SetMargins(0, 0);
167 $this->SetAutoPageBreak(FALSE);
168 $this->setPrintHeader(FALSE);
169 $this->setPrintFooter(FALSE);
170 }
171
172 /**
173 * @param $objectinstance
174 * @param string $methodname
175 */
176 public function SetGenerator($objectinstance, $methodname = 'generateLabel') {
177 $this->generatorMethod = $methodname;
178 $this->generatorObject = $objectinstance;
179 }
180
181 /**
182 * @param string $name
183 * @param bool $convert
184 *
185 * @return float|int|mixed
186 */
187 public function getFormatValue($name, $convert = FALSE) {
188 if (isset($this->format[$name])) {
189 $value = $this->format[$name];
190 $metric = $this->format['metric'];
191 }
192 else {
193 $value = CRM_Utils_Array::value($name, $this->defaults);
194 $metric = $this->defaults['metric'];
195 }
196 if ($convert) {
197 $value = CRM_Utils_PDF_Utils::convertMetric($value, $metric, $this->metricDoc);
198 }
199 return $value;
200 }
201
202 /**
203 * initialize label format settings.
204 *
205 * @param $format
206 * @param $unit
207 */
208 public function LabelSetFormat(&$format, $unit) {
209 $this->defaults = CRM_Core_BAO_LabelFormat::getDefaultValues();
210 $this->format = &$format;
211 $this->formatName = $this->getFormatValue('name');
212 $this->paperSize = $this->getFormatValue('paper-size');
213 $this->orientation = $this->getFormatValue('orientation');
214 $this->fontName = $this->getFormatValue('font-name');
215 $this->charSize = $this->getFormatValue('font-size');
216 $this->fontStyle = $this->getFormatValue('font-style');
217 $this->xNumber = $this->getFormatValue('NX');
218 $this->yNumber = $this->getFormatValue('NY');
219 $this->metricDoc = $unit;
220 $this->marginLeft = $this->getFormatValue('lMargin', TRUE);
221 $this->marginTop = $this->getFormatValue('tMargin', TRUE);
222 $this->xSpace = $this->getFormatValue('SpaceX', TRUE);
223 $this->ySpace = $this->getFormatValue('SpaceY', TRUE);
224 $this->width = $this->getFormatValue('width', TRUE);
225 $this->height = $this->getFormatValue('height', TRUE);
226 $this->paddingLeft = $this->getFormatValue('lPadding', TRUE);
227 $this->paddingTop = $this->getFormatValue('tPadding', TRUE);
228 $paperSize = CRM_Core_BAO_PaperSize::getByName($this->paperSize);
229 $w = CRM_Utils_PDF_Utils::convertMetric($paperSize['width'], $paperSize['metric'], $this->metricDoc);
230 $h = CRM_Utils_PDF_Utils::convertMetric($paperSize['height'], $paperSize['metric'], $this->metricDoc);
231 $this->paper_dimensions = [$w, $h];
232 }
233
234 /**
235 * Generate the pdf of one label (can be modified using SetGenerator)
236 *
237 * @param string $text
238 */
239 public function generateLabel($text) {
240 // paddingLeft is used for both left & right padding so needs to be
241 // subtracted twice from width to get the width that is available for text
242 $args = [
243 'w' => $this->width - 2 * $this->paddingLeft,
244 'h' => 0,
245 'txt' => $text,
246 'border' => 0,
247 'align' => 'L',
248 'fill' => 0,
249 'ln' => 0,
250 'x' => '',
251 'y' => '',
252 'reseth' => TRUE,
253 'stretch' => 0,
254 'ishtml' => FALSE,
255 'autopadding' => FALSE,
256 'maxh' => $this->height,
257 ];
258
259 CRM_Utils_Hook::alterMailingLabelParams($args);
260
261 if ($args['ishtml'] == TRUE) {
262 $this->writeHTMLCell($args['w'], $args['h'],
263 $args['x'], $args['y'],
264 $args['txt'], $args['border'],
265 $args['ln'], $args['fill'],
266 $args['reseth'], $args['align'],
267 $args['autopadding']
268 );
269 }
270 else {
271 $this->multiCell($args['w'], $args['h'],
272 $args['txt'], $args['border'],
273 $args['align'], $args['fill'],
274 $args['ln'], $args['x'],
275 $args['y'], $args['reseth'],
276 $args['stretch'], $args['ishtml'],
277 $args['autopadding'], $args['maxh']
278 );
279 }
280 }
281
282 /**
283 * Print a label.
284 *
285 * @param $texte
286 */
287 public function AddPdfLabel($texte) {
288 if ($this->countX == $this->xNumber) {
289 // Page full, we start a new one
290 $this->AddPage();
291 $this->countX = 0;
292 $this->countY = 0;
293 }
294
295 $posX = $this->marginLeft + ($this->countX * ($this->width + $this->xSpace));
296 $posY = $this->marginTop + ($this->countY * ($this->height + $this->ySpace));
297 $this->SetXY($posX + $this->paddingLeft, $posY + $this->paddingTop);
298 if ($this->generatorMethod) {
299 call_user_func_array([$this->generatorObject, $this->generatorMethod], [$texte]);
300 }
301 else {
302 $this->generateLabel($texte);
303 }
304 $this->countY++;
305
306 if ($this->countY == $this->yNumber) {
307 // End of column reached, we start a new one
308 $this->countX++;
309 $this->countY = 0;
310 }
311 }
312
313 /**
314 * Get the available font names.
315 *
316 * @return array
317 */
318 public function getFontNames() {
319 // Define labels for TCPDF core fonts
320 $fontLabel = [
321 'courier' => ts('Courier'),
322 'helvetica' => ts('Helvetica'),
323 'times' => ts('Times New Roman'),
324 'dejavusans' => ts('Deja Vu Sans (UTF-8)'),
325 ];
326
327 // Check to see if we have any additional fonts to add. You can specify more fonts in
328 // civicrm.settings.php via: $config['CiviCRM Preferences']['additional_fonts']
329 // CRM-13307
330 $additionalFonts = Civi::settings()->get('additional_fonts');
331 if (is_array($additionalFonts)) {
332 $fontLabel = array_merge($fontLabel, $additionalFonts);
333 }
334
335 $tcpdfFonts = $this->fontlist;
336 foreach ($tcpdfFonts as $fontName) {
337 if (array_key_exists($fontName, $fontLabel)) {
338 $list[$fontName] = $fontLabel[$fontName];
339 }
340 }
341
342 return $list;
343 }
344
345 }