Completed
Push — master ( 918968...41e45f )
by Mathieu
06:18
created

PDF::setParams()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 10
ccs 5
cts 5
cp 1
rs 9.4285
cc 2
eloc 6
nc 2
nop 2
crap 2
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')
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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')
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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);
1 ignored issue
show
Bug introduced by
The method merge cannot be called on $this->params (of type array<string,string>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
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) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $key of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
297
            return ${$key};
298
        }
299
300 8
        return compact('uri', 'postParams');
301
    }
302
}
303