Passed
Push — developer ( 0a5a9d...dbf062 )
by Radosław
37:42 queued 18:16
created

YetiForcePDF::output()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 21
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 21
rs 8.8333
c 0
b 0
f 0
cc 7
nc 10
nop 2
1
<?php
2
3
/**
4
 * YetiForcePDF driver file for PDF generation.
5
 *
6
 * @package App\Pdf
7
 *
8
 * @copyright YetiForce S.A.
9
 * @license   YetiForce Public License 5.0 (licenses/LicenseEN.txt or yetiforce.com)
10
 * @author    Rafal Pospiech <[email protected]>
11
 * @author    Radosław Skrzypczak <[email protected]>
12
 * @author	  Mariusz Krzaczkowski <[email protected]>
13
 */
14
15
namespace App\Pdf\Drivers;
16
17
/**
18
 * YetiForcePDF driver class for PDF generation.
19
 */
20
class YetiForcePDF extends Base
21
{
22
	/** {@inheritdoc} */
23
	const DRIVER_NAME = 'LBL_YETIFORCE_PDF';
24
25
	/** @var string Default font. */
26
	protected $font = 'DejaVu Sans';
27
28
	/** @var int Default font size */
29
	protected $fontSize = 10;
30
31
	/** @var \YetiForcePDF\Document PDF generator instance. */
32
	protected $pdf;
33
34
	/** {@inheritdoc} */
35
	public static function isActive(): bool
36
	{
37
		return true;
38
	}
39
40
	/**
41
	 * Constructor.
42
	 */
43
	public function __construct()
44
	{
45
		$this->setInputCharset(\App\Config::main('default_charset') ?? 'UTF-8');
46
		$this->pdf = (new \YetiForcePDF\Document())->init();
47
	}
48
49
	/** {@inheritdoc} */
50
	public function setTopMargin(float $margin)
51
	{
52
		$this->pdf->setDefaultTopMargin($margin);
53
		$this->defaultMargins['top'] = $margin;
54
		return $this;
55
	}
56
57
	/** {@inheritdoc} */
58
	public function setBottomMargin(float $margin)
59
	{
60
		$this->pdf->setDefaultBottomMargin((float) $margin);
61
		$this->defaultMargins['bottom'] = $margin;
62
		return $this;
63
	}
64
65
	/**
66
	 * Set left margin.
67
	 *
68
	 * @param float $margin
69
	 */
70
	public function setLeftMargin(float $margin)
71
	{
72
		$this->pdf->setDefaultLeftMargin((float) $margin);
73
		$this->defaultMargins['left'] = $margin;
74
		return $this;
75
	}
76
77
	/** {@inheritdoc} */
78
	public function setRightMargin(float $margin)
79
	{
80
		$this->pdf->setDefaultRightMargin((float) $margin);
81
		$this->defaultMargins['right'] = $margin;
82
		return $this;
83
	}
84
85
	/** {@inheritdoc} */
86
	public function setHeaderMargin(float $margin)
87
	{
88
		$this->headerMargin = $margin;
89
		return $this;
90
	}
91
92
	/** {@inheritdoc} */
93
	public function setFooterMargin(float $margin)
94
	{
95
		$this->footerMargin = $margin;
96
		return $this;
97
	}
98
99
	/** {@inheritdoc} */
100
	public function setMargins(array $margins)
101
	{
102
		$this->setTopMargin($margins['top'] ?? $this->defaultMargins['top']);
103
		$this->setBottomMargin($margins['bottom'] ?? $this->defaultMargins['bottom']);
104
		$this->setLeftMargin($margins['left'] ?? $this->defaultMargins['left']);
105
		$this->setRightMargin($margins['right'] ?? $this->defaultMargins['right']);
106
		$this->setHeaderMargin($margins['header'] ?? $this->defaultMargins['header']);
107
		$this->setFooterMargin($margins['footer'] ?? $this->defaultMargins['footer']);
108
		return $this;
109
	}
110
111
	/** {@inheritdoc} */
112
	public function setPageSize(string $format, string $orientation = null)
113
	{
114
		$this->pdf->setDefaultFormat($format);
115
		if ($orientation) {
116
			$this->pdf->setDefaultOrientation($orientation);
117
		}
118
		return $this;
119
	}
120
121
	/** {@inheritdoc} */
122
	public function setTitle(string $title)
123
	{
124
		$this->pdf->getMeta()->setTitle($title);
125
		return $this;
126
	}
127
128
	/** {@inheritdoc} */
129
	public function setAuthor(string $author)
130
	{
131
		$this->pdf->getMeta()->setAuthor($author);
132
		return $this;
133
	}
134
135
	/** {@inheritdoc} */
136
	public function setCreator(string $creator)
137
	{
138
		$this->pdf->getMeta()->setCreator($creator);
139
		return $this;
140
	}
141
142
	/** {@inheritdoc} */
143
	public function setSubject(string $subject)
144
	{
145
		$this->pdf->getMeta()->setSubject($subject);
146
		return $this;
147
	}
148
149
	/** {@inheritdoc} */
150
	public function setKeywords(array $keywords)
151
	{
152
		$this->pdf->getMeta()->setKeywords($keywords);
153
		return $this;
154
	}
155
156
	/** {@inheritdoc} */
157
	public function setHeader(string $headerHtml)
158
	{
159
		$this->header = trim($headerHtml);
160
		return $this;
161
	}
162
163
	/** {@inheritdoc} */
164
	public function setFooter(string $footerHtml)
165
	{
166
		$this->footer = trim($footerHtml);
167
		return $this;
168
	}
169
170
	/**
171
	 * Write html.
172
	 *
173
	 * @return $this
174
	 */
175
	public function writeHTML()
176
	{
177
		$this->loadCustomFonts();
178
		$this->pdf->loadHtml($this->getHtml(), $this->charset);
179
		return $this;
180
	}
181
182
	/**
183
	 * Gets full html.
184
	 *
185
	 * @return string
186
	 */
187
	public function getHtml(): string
188
	{
189
		$html = $this->watermark ? $this->wrapWatermark($this->watermark) : '';
190
		$html .= $this->header ? $this->wrapHeaderContent($this->header) : '';
191
		$html .= $this->getBody();
192
		$html .= $this->footer ? $this->wrapFooterContent($this->footer) : '';
193
		return $html;
194
	}
195
196
	/**
197
	 * Wrap header content.
198
	 *
199
	 * @param string $content
200
	 *
201
	 * @return string
202
	 */
203
	public function wrapHeaderContent(string $content): string
204
	{
205
		$style = "padding-top:{$this->headerMargin}px; padding-left:{$this->defaultMargins['left']}px; padding-right:{$this->defaultMargins['right']}px";
206
		return '<div id="header" data-header style="' . $style . '">' . $content . '</div>';
207
	}
208
209
	/**
210
	 * Wrap footer content.
211
	 *
212
	 * @param string $content
213
	 *
214
	 * @return string
215
	 */
216
	public function wrapFooterContent(string $content): string
217
	{
218
		$style = "padding-bottom:{$this->footerMargin}px; padding-left:{$this->defaultMargins['left']}px; padding-right:{$this->defaultMargins['right']}px";
219
		// Modification of the following condition will violate the license!
220
		if (!\App\YetiForce\Shop::check('YetiForceDisableBranding')) {
221
			$content .= '<table style="font-size:6px;width:100%; margin: 0;"><tbody><tr><td style="width:50%">Powered by YetiForce</td></tr></tbody></table>';
222
		}
223
		// Modification of the following condition will violate the license!
224
		return '<div id="footer" data-footer style="' . $style . '">' . $content . '</div>';
225
	}
226
227
	/**
228
	 * Wrap watermark.
229
	 *
230
	 * @param string $watermarkContent
231
	 *
232
	 * @return string
233
	 */
234
	public function wrapWatermark(string $watermarkContent): string
235
	{
236
		return '<div id="watermark" data-watermark style="text-align:center">' . $watermarkContent . '</div>';
237
	}
238
239
	/**
240
	 * Load custom fonts.
241
	 *
242
	 * @return $this
243
	 */
244
	private function loadCustomFonts()
245
	{
246
		$fontsDir = 'layouts' . \DIRECTORY_SEPARATOR . 'resources' . \DIRECTORY_SEPARATOR . 'fonts' . \DIRECTORY_SEPARATOR;
247
		$resolvedDir = \Vtiger_Loader::resolveNameToPath('~' . $fontsDir, 'css');
248
		$customFonts = \App\Json::read($resolvedDir . 'fonts.json');
249
		foreach ($customFonts as &$font) {
250
			$font['file'] = $resolvedDir . $font['file'];
251
		}
252
		\YetiForcePDF\Document::addFonts($customFonts);
253
		return $this;
254
	}
255
256
	/** {@inheritdoc} */
257
	public function loadWatermark()
258
	{
259
		$this->watermark = '';
260
		if (self::WATERMARK_TYPE_IMAGE === $this->template->get('watermark_type') && '' !== trim($this->template->get('watermark_image'))) {
261
			if ($this->template->get('watermark_image')) {
262
				$this->watermark = '<img src="' . $this->template->get('watermark_image') . '" style="opacity:0.1;">';
263
			}
264
		} elseif (self::WATERMARK_TYPE_TEXT === $this->template->get('watermark_type') && '' !== trim($this->template->get('watermark_text'))) {
265
			$this->watermark = '<div style="opacity:0.1;display:inline-block;">' . $this->template->parseVariables($this->template->get('watermark_text')) . '</div>';
266
		}
267
		return $this;
268
	}
269
270
	/** {@inheritdoc} */
271
	public function output($fileName = '', $mode = 'D'): void
272
	{
273
		if (empty($fileName)) {
274
			$fileName = ($this->getFileName() ?: time()) . '.pdf';
275
		}
276
		$this->writeHTML();
277
		$output = $this->pdf->render();
278
		if (!\in_array($mode, ['I', 'D', 'AttachAndOutput'])) {
279
			file_put_contents($fileName, $output);
280
			return;
281
		}
282
		if ('AttachAndOutput' === $mode) {
283
			file_put_contents($fileName, $output);
284
			$fileName = ($this->getFileName() ?: time()) . '.pdf';
285
		}
286
		$destination = 'I' === $mode ? 'inline' : 'attachment';
287
		header('accept-charset: utf-8');
288
		header('content-type: application/pdf; charset=utf-8');
289
		$basename = \App\Fields\File::sanitizeUploadFileName($fileName);
290
		header("content-disposition: {$destination}; filename=\"{$basename}\"");
291
		echo $output;
292
	}
293
}
294