1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace MathieuTu\PDFLayer; |
4
|
|
|
|
5
|
|
|
use GuzzleHttp\Client; |
6
|
|
|
use Illuminate\Contracts\Config\Repository as ConfigRepository; |
7
|
|
|
use Illuminate\Contracts\View\Factory as ViewFactory; |
8
|
|
|
use Illuminate\Filesystem\Filesystem; |
9
|
|
|
use Illuminate\Http\Response; |
10
|
|
|
use Illuminate\Support\Str; |
11
|
|
|
use MathieuTu\PDFLayer\Exceptions\PDFLayerException; |
12
|
|
|
|
13
|
|
|
class PDF |
14
|
|
|
{ |
15
|
|
|
private $httpClient; |
16
|
|
|
private $view; |
17
|
|
|
private $files; |
18
|
|
|
private $config; |
19
|
|
|
private $params; |
20
|
|
|
private $pdf; |
21
|
|
|
|
22
|
13 |
|
public function __construct(Client $httpClient, ConfigRepository $config, Filesystem $files, ViewFactory $view) |
23
|
|
|
{ |
24
|
13 |
|
$this->httpClient = $httpClient; |
25
|
13 |
|
$this->view = $view; |
26
|
13 |
|
$this->files = $files; |
27
|
13 |
|
$this->config = $this->prepareConfig($config); |
28
|
13 |
|
$this->params = $this->prepareParams(); |
29
|
13 |
|
} |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* Load parameters from config file. |
33
|
|
|
* |
34
|
|
|
* @param \Illuminate\Contracts\Config\Repository $config |
35
|
|
|
* |
36
|
|
|
* @return array |
37
|
|
|
*/ |
38
|
13 |
|
private function prepareConfig(ConfigRepository $config) |
39
|
|
|
{ |
40
|
13 |
|
return $config->get('pdflayer'); |
41
|
|
|
} |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* @return \Illuminate\Support\Collection |
45
|
|
|
*/ |
46
|
13 |
|
private function prepareParams() |
47
|
|
|
{ |
48
|
13 |
|
$params = collect($this->config['default_params']); |
49
|
13 |
|
if ($this->config['sandbox']) { |
50
|
13 |
|
$params['test'] = 1; |
51
|
|
|
} |
52
|
|
|
|
53
|
13 |
|
return $params; |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* @param $url |
58
|
|
|
* |
59
|
|
|
* @return $this |
60
|
|
|
*/ |
61
|
1 |
|
public function loadUrl($url) |
62
|
|
|
{ |
63
|
1 |
|
$this->params['document_url'] = urlencode($url); |
64
|
|
|
|
65
|
1 |
|
if (!empty($this->config['secret_keyword'])) { |
66
|
1 |
|
$this->params['secret_key'] = md5($url . $this->config['secret_keyword']); |
67
|
|
|
} |
68
|
|
|
|
69
|
1 |
|
return $this; |
70
|
|
|
} |
71
|
|
|
|
72
|
1 |
|
public function loadView($view, $data = [], $mergeData = [], $encoding = null) |
73
|
|
|
{ |
74
|
1 |
|
$html = $this->view->make($view, $data, $mergeData)->render(); |
75
|
|
|
|
76
|
1 |
|
return $this->loadHTML($html, $encoding); |
77
|
|
|
} |
78
|
|
|
|
79
|
3 |
|
public function loadHTML($html, $encoding = null) |
80
|
|
|
{ |
81
|
3 |
|
$this->params['document_html'] = $html; |
82
|
|
|
|
83
|
3 |
|
if ($encoding) { |
84
|
2 |
|
$this->params['text_encoding'] = $encoding; |
85
|
|
|
} |
86
|
|
|
|
87
|
3 |
|
return $this; |
88
|
|
|
} |
89
|
|
|
|
90
|
1 |
|
public function loadFile($file) |
91
|
|
|
{ |
92
|
1 |
|
$html = file_get_contents($file); |
93
|
1 |
|
$encoding = null; |
94
|
1 |
|
if (isset($http_response_header)) { |
95
|
1 |
|
foreach ($http_response_header as $_header) { |
96
|
1 |
|
if (preg_match("@Content-Type:\s*[\w/]+;\s*?charset=([\S]+)@i", $_header, $matches)) { |
97
|
1 |
|
$encoding = strtoupper($matches[1]); |
98
|
1 |
|
break; |
99
|
|
|
} |
100
|
|
|
} |
101
|
|
|
} |
102
|
1 |
|
$this->loadHTML($html, $encoding); |
103
|
1 |
|
} |
104
|
|
|
|
105
|
1 |
|
public function setPaper($layout, $orientation = 'portrait') |
106
|
|
|
{ |
107
|
1 |
|
$this->params['page_size'] = $layout; |
108
|
1 |
|
$this->params['orientation'] = $orientation; |
109
|
|
|
|
110
|
1 |
|
return $this; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* Return a response with the PDF to show in the browser. |
115
|
|
|
* |
116
|
|
|
* @param string $filename |
117
|
|
|
* |
118
|
|
|
* @throws \InvalidArgumentException |
119
|
|
|
* |
120
|
|
|
* @return \Illuminate\Http\Response |
121
|
|
|
*/ |
122
|
1 |
View Code Duplication |
public function stream($filename = 'document.pdf') |
|
|
|
|
123
|
|
|
{ |
124
|
1 |
|
$output = $this->output(); |
125
|
|
|
|
126
|
1 |
|
return new Response($output, 200, [ |
127
|
1 |
|
'Content-Type' => 'application/pdf', |
128
|
1 |
|
'Content-Disposition' => 'inline; filename="' . $filename . '"', |
129
|
|
|
]); |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* Output the PDF as a string. |
134
|
|
|
* |
135
|
|
|
* @throws \Exception |
136
|
|
|
* |
137
|
|
|
* @return string The rendered PDF as string |
138
|
|
|
*/ |
139
|
4 |
|
public function output() |
140
|
|
|
{ |
141
|
4 |
|
if (!$this->pdf) { |
142
|
4 |
|
$this->render(); |
143
|
|
|
} |
144
|
|
|
|
145
|
4 |
|
return $this->pdf; |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* Prepare the request and make the api call. |
150
|
|
|
* |
151
|
|
|
* @throws \Exception |
152
|
|
|
*/ |
153
|
4 |
|
private function render() |
154
|
|
|
{ |
155
|
4 |
|
list($uri, $postParams) = $this->prepareRequest(); |
156
|
4 |
|
$this->pdf = $this->doRequest($uri, $postParams); |
157
|
4 |
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* @return array |
161
|
|
|
*/ |
162
|
12 |
|
private function prepareRequest() |
163
|
|
|
{ |
164
|
12 |
|
$uri = $this->config['endpoint'] . '?access_key=' . $this->config['access_key']; |
165
|
|
|
|
166
|
12 |
|
$postKeys = ['document_html', 'header_html']; |
167
|
12 |
|
$getParams = $this->params->except($postKeys)->toArray(); |
168
|
|
|
|
169
|
12 |
|
$uri .= '&' . http_build_query($getParams); |
170
|
12 |
|
$postParams = $this->params->diff($getParams)->toArray(); |
171
|
|
|
|
172
|
12 |
|
return [$uri, $postParams]; |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* @param $uri |
177
|
|
|
* @param $postParams |
178
|
|
|
* |
179
|
|
|
* @throws \RuntimeException |
180
|
|
|
* @throws \MathieuTu\PDFLayer\Exceptions\PDFLayerException |
181
|
|
|
* |
182
|
|
|
* @return string |
183
|
|
|
*/ |
184
|
4 |
|
private function doRequest($uri, $postParams) |
185
|
|
|
{ |
186
|
4 |
|
$response = $this->httpClient->post($uri, [ |
187
|
4 |
|
'form_params' => $postParams, |
188
|
|
|
]); |
189
|
|
|
|
190
|
4 |
|
$content = $response->getBody()->getContents(); |
191
|
|
|
|
192
|
4 |
|
$error = json_decode($content); |
193
|
4 |
|
if (is_object($error)) { |
194
|
1 |
|
throw new PDFLayerException($error); |
195
|
|
|
} |
196
|
|
|
|
197
|
4 |
|
return $content; |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
/** |
201
|
|
|
* Make the PDF downloadable by the user. |
202
|
|
|
* |
203
|
|
|
* @param string $filename |
204
|
|
|
* |
205
|
|
|
* @throws \InvalidArgumentException |
206
|
|
|
* |
207
|
|
|
* @return \Illuminate\Http\Response |
208
|
|
|
*/ |
209
|
1 |
View Code Duplication |
public function download($filename = 'document.pdf') |
|
|
|
|
210
|
|
|
{ |
211
|
1 |
|
$output = $this->output(); |
212
|
|
|
|
213
|
1 |
|
return new Response($output, 200, [ |
214
|
1 |
|
'Content-Type' => 'application/pdf', |
215
|
1 |
|
'Content-Disposition' => 'attachment; filename="' . $filename . '"', |
216
|
|
|
]); |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
/** |
220
|
|
|
* Save the PDF to a file. |
221
|
|
|
* |
222
|
|
|
* @param $filename |
223
|
|
|
* |
224
|
|
|
* @return $this |
225
|
|
|
*/ |
226
|
1 |
|
public function save($filename) |
227
|
|
|
{ |
228
|
1 |
|
$this->files->put($filename, $this->output()); |
229
|
|
|
|
230
|
1 |
|
return $this; |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
/** |
234
|
|
|
* @param $name |
235
|
|
|
* @param $arguments |
236
|
|
|
* |
237
|
|
|
* @throws \InvalidArgumentException |
238
|
|
|
* @throws \BadMethodCallException |
239
|
|
|
* |
240
|
|
|
* @return $this|mixed |
241
|
|
|
*/ |
242
|
1 |
|
public function __call($name, $arguments) |
243
|
|
|
{ |
244
|
1 |
|
if (Str::startsWith($name, 'set')) { |
245
|
1 |
|
$propertyCamel = Str::substr($name, Str::length('set')); |
246
|
1 |
|
$property = Str::snake($propertyCamel); |
247
|
|
|
|
248
|
1 |
|
$this->params[$property] = $arguments[0]; |
249
|
|
|
|
250
|
1 |
|
return $this; |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
throw new \BadMethodCallException('Call to undefined method ' . static::class . '::' . $name . '()'); |
254
|
|
|
} |
255
|
|
|
|
256
|
1 |
|
public function __set($name, $value) |
257
|
|
|
{ |
258
|
1 |
|
return $this->params[$name] = $value; |
259
|
|
|
} |
260
|
|
|
|
261
|
1 |
|
public function addParams(array $params) |
262
|
|
|
{ |
263
|
1 |
|
return $this->setParams($params); |
264
|
|
|
} |
265
|
|
|
|
266
|
2 |
|
public function setParams(array $params, $replace = false) |
267
|
|
|
{ |
268
|
2 |
|
if ($replace) { |
269
|
1 |
|
$this->params = collect($params); |
270
|
|
|
} else { |
271
|
2 |
|
$this->params = $this->params->merge($params); |
|
|
|
|
272
|
|
|
} |
273
|
|
|
|
274
|
2 |
|
return $this; |
275
|
|
|
} |
276
|
|
|
|
277
|
1 |
|
public function replaceParams(array $params) |
278
|
|
|
{ |
279
|
1 |
|
return $this->setParams($params, true); |
280
|
|
|
} |
281
|
|
|
|
282
|
|
|
public function seeParams() |
283
|
|
|
{ |
284
|
|
|
return $this->params->toArray(); |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
/** |
288
|
|
|
* @param string $key uri or postParams |
289
|
|
|
* |
290
|
|
|
* @return array |
291
|
|
|
*/ |
292
|
8 |
|
public function seeRequestArgs($key = null) |
293
|
|
|
{ |
294
|
8 |
|
list($uri, $postParams) = $this->prepareRequest(); |
295
|
|
|
|
296
|
8 |
|
if ($key) { |
|
|
|
|
297
|
|
|
return ${$key}; |
298
|
|
|
} |
299
|
|
|
|
300
|
8 |
|
return compact('uri', 'postParams'); |
301
|
|
|
} |
302
|
|
|
} |
303
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.