Completed
Push — develop ( 264d47...05a799 )
by Barry
02:39
created

Pdfcrowd::httpPost()   B

Complexity

Conditions 4
Paths 20

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4.0092

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 11
cts 12
cp 0.9167
rs 8.9197
c 0
b 0
f 0
cc 4
eloc 13
nc 20
nop 3
crap 4.0092
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Swis\PdfcrowdClient;
6
7
use CURLFile;
8
use Swis\PdfcrowdClient\Exceptions\PdfcrowdException;
9
use Swis\PdfcrowdClient\Http\FactoryInterface;
10
use Swis\PdfcrowdClient\Http\RequestFactory;
11
use Swis\PdfcrowdClient\Http\RequestInterface;
12
13
class Pdfcrowd
14
{
15
    /** @var array */
16
    private $fields;
17
18
    /** @var string */
19
    private $scheme;
20
21
    /** @var int */
22
    private $port;
23
24
    /** @var string */
25
    private $api_prefix;
26
27
    /** @var int */
28
    private $curlopt_timeout;
29
30
    /** @var string */
31
    private $hostname;
32
33
    /** @var string */
34
    private $user_agent;
35
36
    /** @var int */
37
    private $num_tokens_before = false;
38
39
    /** @var int */
40
    private $http_code;
41
42
    /** @var string */
43
    private $error;
44
45
    private $outstream;
46
47
    /** @var FactoryInterface */
48
    protected $requestFactory;
49
50
    /* @var RequestInterface */
51
    private $request;
52
53
    /** @var bool  */
54
    private $track_tokens = false;
55
56
    public static $client_version = '2.7';
57
    public static $http_port = 80;
58
    public static $https_port = 443;
59
    public static $api_host = 'pdfcrowd.com';
60
61
    private $proxy_name = null;
62
    private $proxy_port = null;
63
    private $proxy_username = '';
64
    private $proxy_password = '';
65
66
    const SINGLE_PAGE = 1;
67
    const CONTINUOUS = 2;
68
    const CONTINUOUS_FACING = 3;
69
70
    const NONE_VISIBLE = 1;
71
    const THUMBNAILS_VISIBLE = 2;
72
    const FULLSCREEN = 3;
73
74
    const FIT_WIDTH = 1;
75
    const FIT_HEIGHT = 2;
76
    const FIT_PAGE = 3;
77
78
    /**
79
     * Pdfcrowd constructor.
80
     *
81
     * @param string $username
82
     * @param string $key
83
     */
84 44
    public function __construct(string $username, string $key)
85
    {
86 44
        $this->hostname = self::$api_host;
87
88 44
        $this->useSSL(true);
89
90
        // todo: rename fields to options
91 44
        $this->fields = [
92 44
            'username' => $username,
93 44
            'key' => $key,
94 44
            'pdf_scaling_factor' => 1,
95 44
            'html_zoom' => 200,
96
        ];
97
98 44
        $this->user_agent = 'pdfcrowd_php_client_'.self::$client_version.'_(http://pdfcrowd.com)';
99
100 44
        $this->requestFactory = new RequestFactory();
101 44
    }
102
103
    /**
104
     * This method allows you to override the default CurlRequest object. Added for testing purposes.
105
     *
106
     * @param \Swis\PdfcrowdClient\Http\FactoryInterface $requestFactory
107
     */
108 40
    public function setRequestFactory(FactoryInterface $requestFactory)
109
    {
110 40
        $this->requestFactory = $requestFactory;
111 40
    }
112
113
    /**
114
     * Each httpPost-call uses a clean request object.
115
     *
116
     * @return \Swis\PdfcrowdClient\Http\RequestInterface
117
     * @throws \Swis\PdfcrowdClient\Exceptions\PdfcrowdException
118
     */
119 38
    protected function getNewRequestObject(): RequestInterface
120
    {
121 38
        $request = $this->requestFactory->create();
122
123 38
        if (!$request instanceof RequestInterface) {
124
            throw new PdfcrowdException('Request object must extend the RequestInterface');
125
        }
126
127 38
        return $request;
128
    }
129
130
    /**
131
     * Converts an in-memory html document.
132
     *
133
     * @param string $src       a string containing a html document
134
     * @param null   $outstream output stream, if null then the return value is a string containing the PDF
135
     *
136
     * @return mixed
137
     * @throws \Swis\PdfcrowdClient\Exceptions\PdfcrowdException
138
     */
139 38
    public function convertHtml($src, $outstream = null)
140
    {
141 38
        if (!$src) {
142 2
            throw new PdfcrowdException('convertHTML(): the src parameter must not be empty');
143
        }
144
145 36
        $this->fields['src'] = $src;
146
147
        // todo: create uri from prefx + constant value
148 36
        $uri = $this->api_prefix.'/pdf/convert/html/';
149
150 36
        if ($this->track_tokens) {
151 2
            $this->num_tokens_before = $this->numTokens();
152
        }
153
154 36
        return $this->httpPost($uri, $this->fields, $outstream);
155
    }
156
157
    /**
158
     * Converts an in-memory html document.
159
     *
160
     * @param string $src       a path to an html file
161
     * @param null   $outstream output stream, if null then the return value is a string containing the PDF
162
     *
163
     * @return mixed
164
     * @throws \Swis\PdfcrowdClient\Exceptions\PdfcrowdException
165
     */
166
    public function convertFile(string $src, $outstream = null)
167
    {
168
        $src = trim($src);
169
170
        if (!file_exists($src)) {
171
            $cwd = getcwd();
172
            throw new PdfcrowdException("convertFile(): '{$src}' not found
173
                        Possible reasons:
174
                         1. The file is missing.
175
                         2. You misspelled the file name.
176
                         3. You use a relative file path (e.g. 'index.html') but the current working
177
                            directory is somewhere else than you expect: '${cwd}'
178
                            Generally, it is safer to use an absolute file path instead of a relative one.
179
                        ");
180
        }
181
182
        if (is_dir($src)) {
183
            throw new PdfcrowdException("convertFile(): '{$src}' must be file, not a directory");
184
        }
185
186
        if (!is_readable($src)) {
187
            throw new PdfcrowdException(
188
                "convertFile(): cannot read '{$src}', please check if the process has sufficient permissions"
189
            );
190
        }
191
192
        if (!filesize($src)) {
193
            throw new PdfcrowdException("convertFile(): '{$src}' must not be empty");
194
        }
195
196
        if (version_compare(PHP_VERSION, '5.5.0') >= 0) {
197
            $this->fields['src'] = new CurlFile($src);
198
        } else {
199
            $this->fields['src'] = '@'.$src;
200
        }
201
202
        $uri = $this->api_prefix.'/pdf/convert/html/';
203
204
        if ($this->track_tokens) {
205
            $this->num_tokens_before = $this->numTokens();
206
        }
207
208
        return $this->httpPost($uri, $this->fields, $outstream);
209
    }
210
211
    /**
212
     * Converts a web page.
213
     *
214
     * @param string $src       a web page URL
215
     * @param null   $outstream output stream, if null then the return value is a string containing the PDF
216
     *
217
     * @return mixed
218
     * @throws \Swis\PdfcrowdClient\Exceptions\PdfcrowdException
219
     */
220
    public function convertURI(string $src, $outstream = null)
221
    {
222
        $src = trim($src);
223
        if (!preg_match("/^https?:\/\/.*/i", $src)) {
224
            throw new PdfcrowdException("convertURI(): the URL must start with http:// or https:// (got '$src')");
225
        }
226
227
        $this->fields['src'] = $src;
228
        $uri = $this->api_prefix.'/pdf/convert/uri/';
229
230
        if ($this->track_tokens) {
231
            $this->num_tokens_before = $this->numTokens();
232
        }
233
234
        return $this->httpPost($uri, $this->fields, $outstream);
235
    }
236
237
    /**
238
     * Returns the number of available conversion tokens.
239
     *
240
     * @return int
241
     */
242
    public function numTokens(): int
243
    {
244 4
        $username = $this->fields['username'];
245 4
        $uri = $this->api_prefix."/user/{$username}/tokens/";
246
        $arr = [
247 4
            'username' => $this->fields['username'],
248 4
            'key' => $this->fields['key'],
249
        ];
250
251 4
        $ntokens = $this->httpPost($uri, $arr, null);
252
253 4
        $response = (string) $ntokens;
254
255 4
        return (int) $response;
256
    }
257
258
    /**
259
     * Get the number of tokens used in the last conversion.
260
     * This is only possible if you enable tracking tokens using trackTokens(true).
261
     *
262
     * @see trackTokens()
263
     *
264
     * @return int
265
     * @throws \Swis\PdfcrowdClient\Exceptions\PdfcrowdException
266
     */
267
    public function getUsedTokens(): int
268
    {
269 6
        if (!$this->track_tokens) {
270 2
            throw new PdfcrowdException(
271 2
                'getUsedTokens() only works if you enable tracking tokens with trackTokens(true)'
272
            );
273
        }
274
275 4
        if ($this->num_tokens_before === false) {
276 2
            throw new PdfcrowdException(
277 2
                'getUsedTokens() should not be called on its own, call a convert call first.'
278
            );
279
        }
280
281 2
        $num_tokens_after = $this->numTokens();
282
283 2
        return (int) $this->num_tokens_before - $num_tokens_after;
284
    }
285
286
    /**
287
     * Track how many tokens are available before each request.
288
     * After a request you can ask the number of used tokens with getUsedTokens.
289
     *
290
     * @see getUsedTokens()
291
     *
292
     * @param bool $trackTokens
293
     */
294
    public function trackTokens(bool $trackTokens = true)
295
    {
296 8
        $this->track_tokens = $trackTokens;
297 8
    }
298
299
    /**
300
     * Turn SSL on or off.
301
     *
302
     * @param bool $use_ssl
303
     */
304
    public function useSSL(bool $use_ssl)
305
    {
306 44
        if ($use_ssl) {
307 44
            $this->port = self::$https_port;
308 44
            $this->scheme = 'https';
309
        } else {
310 2
            $this->port = self::$http_port;
311 2
            $this->scheme = 'http';
312
        }
313
314 44
        $this->api_prefix = "{$this->scheme}://{$this->hostname}/api";
315 44
    }
316
317
    public function setPageWidth($value)
318
    {
319 2
        $this->fields['width'] = $value;
320 2
    }
321
322
    public function setPageHeight($value)
323
    {
324 2
        $this->fields['height'] = $value;
325 2
    }
326
327
    public function setHorizontalMargin($value)
328
    {
329
        $this->fields['margin_right'] = $this->fields['margin_left'] = $value;
330
    }
331
332
    public function setVerticalMargin($value)
333
    {
334
        $this->fields['margin_top'] = $this->fields['margin_bottom'] = $value;
335
    }
336
337
    public function setBottomMargin($value)
338
    {
339
        $this->fields['margin_bottom'] = $value;
340
    }
341
342
    public function setPageMargins($top, $right, $bottom, $left)
343
    {
344
        $this->fields['margin_top'] = $top;
345
        $this->fields['margin_right'] = $right;
346
        $this->fields['margin_bottom'] = $bottom;
347
        $this->fields['margin_left'] = $left;
348
    }
349
350
    /**
351
     * If value is set to True then the PDF is encrypted. This prevents search engines from indexing the document.
352
     * The default is False.
353
     *
354
     * @param bool $val
355
     */
356
    public function setEncrypted(bool $val = true)
357
    {
358
        $this->setOrUnset($val, 'encrypted');
359
    }
360
361
    /**
362
     * Protects the PDF with a user password. When a PDF has a user password, it must be supplied in order to view the
363
     * document and to perform operations allowed by the access permissions. At most 32 characters.
364
     *
365
     * @param string $pwd
366
     */
367
    public function setUserPassword(string $pwd)
368
    {
369
        $this->setOrUnset($pwd, 'user_pwd');
370
    }
371
372
    /**
373
     * Protects the PDF with an owner password. Supplying an owner password grants unlimited access to the PDF
374
     * including changing the passwords and access permissions. At most 32 characters.
375
     *
376
     * @param string $pwd
377
     */
378
    public function setOwnerPassword(string $pwd)
379
    {
380
        $this->setOrUnset($pwd, 'owner_pwd');
381
    }
382
383
    /**
384
     * Set value to True disables printing the generated PDF. The default is False.
385
     *
386
     * @param bool $val
387
     */
388
    public function setNoPrint(bool $val = true)
389
    {
390
        $this->setOrUnset($val, 'no_print');
391
    }
392
393
    /**
394
     * Set value to True to disable modifying the PDF. The default is False.
395
     *
396
     * @param bool $val
397
     */
398
    public function setNoModify(bool $val = true)
399
    {
400
        $this->setOrUnset($val, 'no_modify');
401
    }
402
403
    /**
404
     * Set value to True to disable extracting text and graphics from the PDF. The default is False.
405
     *
406
     * @param bool $val
407
     */
408
    public function setNoCopy(bool $val = true)
409
    {
410
        $this->setOrUnset($val, 'no_copy');
411
    }
412
413
    /**
414
     * Specifies the initial page layout when the PDF is opened in a viewer.
415
     *
416
     * Possible values:
417
     *   \Swis\PdfcrowdClient\Pdfcrowd::SINGLE_PAGE
418
     *   \Swis\PdfcrowdClient\Pdfcrowd::CONTINUOUS
419
     *   \Swis\PdfcrowdClient\Pdfcrowd::CONTINUOUS_FACING
420
     *
421
     * @param int $value
422
     */
423
    public function setPageLayout(int $value)
424
    {
425
        assert($value > 0 && $value <= 3);
426
        $this->fields['page_layout'] = $value;
427
    }
428
429
    /**
430
     * Specifies the appearance of the PDF when opened.
431
     *
432
     * Possible values:
433
     *   \Swis\PdfcrowdClient\Pdfcrowd::NONE_VISIBLE
434
     *   \Swis\PdfcrowdClient\Pdfcrowd::THUMBNAILS_VISIBLE
435
     *   \Swis\PdfcrowdClient\Pdfcrowd::FULLSCREEN
436
     *
437
     * @param int $value
438
     */
439
    public function setPageMode(int $value)
440
    {
441
        assert($value > 0 && $value <= 3);
442
        $this->fields['page_mode'] = $value;
443
    }
444
445
    /**
446
     * @param string $value
447
     */
448
    public function setFooterText(string $value)
449
    {
450
        $this->setOrUnset($value, 'footer_text');
451
    }
452
453
    /**
454
     * Set value to False to disable printing images to the PDF. The default is True.
455
     *
456
     * @param bool $value
457
     */
458
    public function enableImages(bool $value = true)
459
    {
460
        $this->setOrUnset(!$value, 'no_images');
461
    }
462
463
    /**
464
     * Set value to False to disable printing backgrounds to the PDF. The default is True.
465
     *
466
     * @param bool $value
467
     */
468
    public function enableBackgrounds(bool $value = true)
469
    {
470
        $this->setOrUnset(!$value, 'no_backgrounds');
471
    }
472
473
    /**
474
     * Set HTML zoom in percents. It determines the precision used for rendering of the HTML content. Despite its name,
475
     * it does not zoom the HTML content. Higher values can improve glyph positioning and can lead to overall better
476
     * visual appearance of generated PDF .The default value is 200.
477
     *
478
     * @see setPdfScalingFactor
479
     *
480
     * @param int $value
481
     */
482
    public function setHtmlZoom(int $value)
483
    {
484
        $this->setOrUnset($value, 'html_zoom');
485
    }
486
487
    /**
488
     * Set value to False to disable JavaScript in web pages. The default is True.
489
     *
490
     * @param bool $value
491
     */
492
    public function enableJavaScript(bool $value = true)
493
    {
494
        $this->setOrUnset(!$value, 'no_javascript');
495
    }
496
497
    /**
498
     * Set value to False to disable hyperlinks in the PDF. The default is True.
499
     *
500
     * @param bool $value
501
     */
502
    public function enableHyperlinks(bool $value = true)
503
    {
504
        $this->setOrUnset(!$value, 'no_hyperlinks');
505
    }
506
507
    /**
508
     * Value is the text encoding used when none is specified in a web page. The default is utf-8.
509
     *
510
     * @param string $value
511
     */
512
    public function setDefaultTextEncoding(string $value)
513
    {
514
        $this->setOrUnset($value, 'text_encoding');
515
    }
516
517
    /**
518
     * If value is True then the print CSS media type is used (if available).
519
     *
520
     * @param bool $value
521
     */
522
    public function usePrintMedia(bool $value = true)
523
    {
524
        $this->setOrUnset($value, 'use_print_media');
525
    }
526
527
    /**
528
     * Prints at most npages pages.
529
     *
530
     * @param int $value
531
     */
532
    public function setMaxPages(int $value)
533
    {
534
        $this->fields['max_pages'] = $value;
535
    }
536
537
    /**
538
     * @param bool $value
539
     */
540
    public function enablePdfcrowdLogo(bool $value = true)
541
    {
542
        $this->setOrUnset($value, 'pdfcrowd_logo');
543
    }
544
545
    /**
546
     * value specifies the appearance of the PDF when opened.
547
     *
548
     * Possible values:
549
     *   \Swis\Pdfcrowd\Pdfcrowd::FIT_WIDTH
550
     *   \Swis\Pdfcrowd\Pdfcrowd::FIT_HEIGHT
551
     *   \Swis\Pdfcrowd\Pdfcrowd::FIT_PAGE
552
     *
553
     * @param int $value
554
     */
555
    public function setInitialPdfZoomType(int $value)
556
    {
557
        assert($value > 0 && $value <= 3);
558
        $this->fields['initial_pdf_zoom_type'] = $value;
559
    }
560
561
    /**
562
     * value specifies the initial page zoom of the PDF when opened.
563
     *
564
     * @param $value
565
     */
566
    public function setInitialPdfExactZoom($value)
567
    {
568
        $this->fields['initial_pdf_zoom_type'] = 4;
569
        $this->fields['initial_pdf_zoom'] = $value;
570
    }
571
572
    /**
573
     * The scaling factor used to convert between HTML and PDF. The default value is 1.0.
574
     *
575
     * @param float $value
576
     */
577
    public function setPdfScalingFactor(float $value)
578
    {
579
        $this->fields['pdf_scaling_factor'] = $value;
580
    }
581
582
    /**
583
     * Sets the author field in the created PDF.
584
     *
585
     * @param string $value
586
     */
587
    public function setAuthor(string $value)
588
    {
589
        $this->fields['author'] = $value;
590
    }
591
592
    /**
593
     * If value is True then the conversion will fail when the source URI returns 4xx or 5xx HTTP status code. The
594
     * default is False.
595
     *
596
     * @param bool $value
597
     */
598
    public function setFailOnNon200(bool $value)
599
    {
600
        $this->fields['fail_on_non200'] = $value;
601
    }
602
603
    /**
604
     * Places the specified html code inside the page footer. The following variables are expanded:
605
     *   %u - URL to convert.
606
     *   %p - The current page number.
607
     *   %n - Total number of pages.
608
     *
609
     * @param string $value
610
     */
611
    public function setFooterHtml(string $value)
612
    {
613
        $this->fields['footer_html'] = $value;
614
    }
615
616
    /**
617
     * Loads HTML code from the specified url and places it inside the page footer. See setFooterHtml for the list of
618
     * variables that are expanded.
619
     *
620
     * @see setFooterHtml
621
     *
622
     * @param string $value
623
     */
624
    public function setFooterUrl(string $value)
625
    {
626
        $this->fields['footer_url'] = $value;
627
    }
628
629
    /**
630
     * Places the specified html code inside the page header. See setFooterHtml for the list of variables that are
631
     * expanded.
632
     *
633
     * @see setFooterHtml
634
     *
635
     * @param string $value
636
     */
637
    public function setHeaderHtml(string $value)
638
    {
639
        $this->fields['header_html'] = $value;
640
    }
641
642
    /**
643
     * Loads HTML code from the specified url and places it inside the page header. See setFooterHtml for the list of
644
     * variables that are expanded.
645
     *
646
     * @see setFooterHtml
647
     *
648
     * @param string $value
649
     */
650
    public function setHeaderUrl(string $value)
651
    {
652
        $this->fields['header_url'] = $value;
653
    }
654
655
    /**
656
     * The page background color in RRGGBB hexadecimal format.
657
     *
658
     * @param string $value
659
     */
660
    public function setPageBackgroundColor(string $value)
661
    {
662
        $this->fields['page_background_color'] = $value;
663
    }
664
665
    /**
666
     * Does not print the body background. Requires the following CSS rule to be declared:
667
     *   body {background-color:rgba(255,255,255,0.0);}
668
     *
669
     * @param bool $value
670
     */
671
    public function setTransparentBackground(bool $value = true)
672
    {
673
        $this->setOrUnset($value, 'transparent_background');
674
    }
675
676
    /**
677
     * An offset between physical and logical page numbers. The default value is 0.
678
     *
679
     * @example if set to "1" then the page numbering will start with 1 on the second page.
680
     *
681
     * @param int $value
682
     */
683
    public function setPageNumberingOffset(int $value)
684
    {
685
        $this->fields['page_numbering_offset'] = $value;
686
    }
687
688
    /**
689
     * Value is a comma seperated list of physical page numbers on which the header a footer are not printed. Negative
690
     * numbers count backwards from the last page: -1 is the last page, -2 is the last but one page, and so on.
691
     *
692
     * @example "1,-1" will not print the header and footer on the first and the last page.
693
     *
694
     * @param string $value
695
     */
696
    public function setHeaderFooterPageExcludeList(string $value)
697
    {
698 2
        $this->fields['header_footer_page_exclude_list'] = $value;
699 2
    }
700
701
    /**
702
     * url is a public absolute URL of the watermark image (must start either with http:// or https://). The supported
703
     * formats are PNG and JPEG. offset_x and offset_y is the watermark offset in units. The default offset is (0,0).
704
     *
705
     * @param string $url
706
     * @param int    $offset_x
707
     * @param int    $offset_y
708
     */
709
    public function setWatermark(string $url, $offset_x = 0, $offset_y = 0)
710
    {
711 6
        $this->fields['watermark_url'] = $url;
712 6
        $this->fields['watermark_offset_x'] = $offset_x;
713 6
        $this->fields['watermark_offset_y'] = $offset_y;
714 6
    }
715
716
    /**
717
     * Rotates the watermark by angle degrees.
718
     *
719
     * @param int $angle
720
     */
721
    public function setWatermarkRotationsetWatermarkRotation(int $angle)
722
    {
723 2
        $this->fields['watermark_rotation'] = $angle;
724 2
    }
725
726
    /**
727
     * When value is set to True then the watermark is be placed in the background. By default, the watermark is
728
     * placed in the foreground.
729
     *
730
     * @param bool $val
731
     */
732
    public function setWatermarkInBackground(bool $val = true)
733
    {
734 4
        $this->setOrUnset($val, 'watermark_in_background');
735 4
    }
736
737
    /**
738
     * @param string $proxyname
739
     * @param int    $port
740
     * @param string $username
741
     * @param string $password
742
     */
743
    public function setProxy(string $proxyname, int $port, string $username = '', string $password = '')
744
    {
745 2
        $this->proxy_name = $proxyname;
746 2
        $this->proxy_port = $port;
747 2
        $this->proxy_username = $username;
748 2
        $this->proxy_password = $password;
749 2
    }
750
751
    /**
752
     * @param string $user_agent
753
     */
754
    public function setUserAgent(string $user_agent)
755
    {
756 2
        $this->user_agent = $user_agent;
757 2
    }
758
759
    /**
760
     * @param int $timeout
761
     */
762
    public function setTimeout(int $timeout)
763
    {
764 2
        if (is_int($timeout) && $timeout > 0) {
765 2
            $this->curlopt_timeout = $timeout;
766
        }
767 2
    }
768
769
    /**
770
     * @param string $url
771
     * @param        $postfields
772
     * @param        $outstream
773
     *
774
     * @return mixed
775
     * @throws \Swis\PdfcrowdClient\Exceptions\PdfcrowdException
776
     */
777
    private function httpPost(string $url, array $postfields, $outstream)
778
    {
779 38
        $this->request = $this->buildRequest($url, $postfields, $outstream);
780
781
        try {
782 38
            $response = $this->request->execute();
783
784 36
            $this->http_code = $this->request->getHttpStatusCode();
785 2
        } catch (\Exception $e) {
786 2
            throw new PdfcrowdException("Unknown error during request to Pdfcrowd", 0, $e);
787 36
        } finally {
788 38
            $this->request->close();
789
        }
790
791 36
        if ($this->http_code !== 200) {
792 2
            throw new PdfcrowdException((string) $response, $this->http_code);
793
        }
794
795 34
        if ($outstream === null) {
796 34
            return $response;
797
        }
798
    }
799
800
    protected function buildRequest(string $url, array $postfields, $outstream)
801
    {
802 38
        $request = $this->getNewRequestObject();
803
804 38
        $request->setUserAgent($this->user_agent);
805
806 38
        if (isset($this->curlopt_timeout)) {
807 2
            $request->setTimeout($this->curlopt_timeout);
808
        }
809
810 38
        if ($outstream) {
811
            $this->outstream = $outstream;
812
            $request->setOption(CURLOPT_WRITEFUNCTION, [$this, 'receiveToStream']);
813
        }
814
815 38
        if ($this->scheme == 'https' && self::$api_host == 'pdfcrowd.com') {
816 36
            $request->setVerifySsl(true);
817
        } else {
818 2
            $request->setVerifySsl(false);
819
        }
820
821 38
        if ($this->proxy_name) {
822 2
            $request->setProxy($this->proxy_name, $this->proxy_port);
823 2
            if ($this->proxy_username) {
824 2
                $request->setProxyAuth($this->proxy_username, $this->proxy_password);
825
            }
826
        }
827
828 38
        $request->setUrl($url);
829
830 38
        $request->setPort($this->port);
831
832 38
        $request->setBody($postfields);
833
834 38
        return $request;
835
    }
836
837
    /**
838
     * @see http://php.net/manual/en/function.curl-setopt.php and look for CURLOPT_WRITEFUNCTION
839
     *
840
     * @param $curl
841
     * @param $data
842
     *
843
     * @return bool|int
844
     * @throws \Swis\PdfcrowdClient\Exceptions\PdfcrowdException
845
     */
846
    private function receiveToStream($curl, $data)
847
    {
848
        if ($this->http_code == 0) {
849
            $this->http_code = (int) curl_getinfo($curl, CURLINFO_HTTP_CODE);
850
        }
851
852
        if ($this->http_code >= 400) {
853
            $this->error = $this->error.$data;
854
855
            return strlen($data);
856
        }
857
858
        $written = fwrite($this->outstream, $data);
859
        if ($written != strlen($data)) {
860
            if (get_magic_quotes_runtime()) {
861
                throw new PdfcrowdException("
862
                    Cannot write the PDF file because the 'magic_quotes_runtime' setting is enabled. Please disable 
863
                    it either in your php.ini file, or in your code by calling 'set_magic_quotes_runtime(false)'.
864
                ");
865
            } else {
866
                throw new PdfcrowdException('Writing the PDF file failed. The disk may be full.');
867
            }
868
        }
869
870
        return $written;
871
    }
872
873
    /**
874
     * Set or unset a parameter that will be sent with the request to the pdfcrowd API.
875
     *
876
     * @param mixed $val
877
     * @param string $field
878
     */
879
    private function setOrUnset($val, string $field)
880
    {
881 4
        if ($val) {
882 4
            $this->fields[$field] = $val;
883
        } else {
884 2
            unset($this->fields[$field]);
885
        }
886 4
    }
887
}
888