Giter Site home page Giter Site logo

gotenberg-php's People

Contributors

alexskrypnyk avatar changingterry avatar dependabot[bot] avatar dontfreakout avatar gulien avatar mariusjp avatar rreynier avatar vidschofelix avatar yanbuatois avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

gotenberg-php's Issues

not working php:8.3.4

php:8.3.4
gotenberg:8.3.0
Executing the following code always returns:code=405, message=Method Not Allowed
$request = Gotenberg::libreOffice("http://gotenberg:3000") ->convert(Stream::path(BASE_PATH . '/storage/pdf/2023.docx')); Gotenberg::save($request, BASE_PATH . '/storage');

Docker logs
{"level":"error","ts":1712074302.3096998,"logger":"api","msg":"code=405, message=Method Not Allowed","trace":"86ea7b13-eeb4-4cb6-b208-b6eca9267db6","remote_ip":"172.19.0.3","host":"gotenberg:3000","uri":"/forms/libreoffice/convert","method":"PUT","path":"/forms/libreoffice/convert","referer":"","user_agent":"GuzzleHttp/7","status":405,"latency":58400,"latency_human":"58.4µs","bytes_in":0,"bytes_out":18}

Custom header and footer no rendered.

Hi,

I can't figure out what I am do wrong when setting header and footer, or if this is a bug.
PHP is in version 8.2.12
Gotenberg docker version 8.3.0

If I do not set them, nothing in pdf file. --> ok
If I set them to "", default browser values. --> ok

$req->header(Stream::string($rootDir."header.html", "")); 
$req->footer(Stream::string($rootDir."footer.html', ""));

image

If I set anything else, nothing appears.

$req = Gotenberg::chromium('http://gotenberg:3000')->pdf();
$req->outputFilename('test');
$req->header(Stream::string($rootDir.'header.html', '<html><head></head><body>HEADER</body></html>'));
$req->footer(Stream::string($rootDir.'footer.html', '<html><head></head><body>FOOTER</body></html>'));
$req = $req->html(Stream::string($rootDir.'html.html', '<html><head></head><body>CONTENT '.date('Y-m-d H:i:s').'</body></html>'));
$res = Gotenberg::save($req, $rootDir);

image

How to handle large file conversion (4gb)

Hello,

Thanks for the wonderful library. How to handle large file conversion?
I can see you have already used stream but i still get internal 500 error.

Any suggestions?

How to loop to merge pdf

Sorry for a newbies question,

I want to merge pdf with pdfengine merge I have a loop for that based on the number of document to get.

I think to use this function :

use Gotenberg\Gotenberg;
use Gotenberg\Stream;

$request = Gotenberg::pdfEngines($apiUrl)
    ->merge(
        Stream::path('/path/to/my.pdf'),
        Stream::path('/path/to/my2.pdf')
    );

How can I loop to add Stream::path ?

Thanks for your feedback.

Best regards

Tag version

Hi,

The recent tag does not follow the semver structure like old tags. Plus the tag version jumped from 1.1 to 1.18

Laravel Sail Internal URLs not working 8.2.0

I'm having an issue on 8.2.0 (Maybe related to gotenberg/gotenberg#403?)

Using Laravel + Sail on WSL2

docker-compose.yml
    gotenberg:
        image: gotenberg/gotenberg:8
        extra_hosts:
            - 'host.docker.internal:host-gateway'
        ports:
            - '${FORWARD_GOTENBERG_PORT:-3000}:3000'
        volumes:
            - './public/fonts:/usr/local/share/fonts'
        command:
            - "gotenberg"
            - "--log-level=debug"
        networks:
            - sail

ive made a static page at /sample which literally says just "Hello, World!"

from inside the gotenberg container curl http://laravel.test/sample works fine

I can run the following from inside the laravel app container (not the gotenberg container)

curl \
--request POST http://gotenberg:3000/forms/chromium/convert/url \
--form url=http://laravel.test/sample \
-o my.pdf

it works fine, my.pdf appears in the project root. with the words "Hello, World!" on it.

But from the application when I run (gotenberg/gotenberg-php)

$request = Gotenberg::chromium(config('gotenberg.url'))
                            ->pdf()
                            ->failOnConsoleExceptions()
                            ->outputFilename('my-custom-pdf')
                            ->url('http://laravel.test:80/sample');

        $response = Gotenberg::send($request);

        return $response
            ->withHeader('Content-Type', 'application/pdf')
            ->withHeader('Content-Disposition', 'inline; filename="generated.pdf"');

I keep getting:

ypa-filament-app-gotenberg-1  | {"level":"error","ts":1709274087.9005635,"logger":"api","msg":"convert URL to PDF: conv
ert to PDF: context deadline exceeded","trace":"efa04a81-fb5a-4cfe-abb3-80e0d6e81a00","remote_ip":"172.23.0.8","host":"
gotenberg:3000","uri":"/forms/chromium/convert/url","method":"POST","path":"/forms/chromium/convert/url","referer":"","
user_agent":"GuzzleHttp/7","status":503,"latency":30000270232,"latency_human":"30.000270232s","bytes_in":316,"bytes_out":19}

P.S. if i call ->html(Stream::string('sample', view('sample')->render())) though it does work. its only url() thats the problem. But if I have any images in the view the same timeout happens. The image urls also are something like 'http://localhost/img/example.jpg' and I don't think the Gotenberg container can resolve localhost so I'm not even sure what the correct implementation is.

Been fighting this all day. Please help 🙏

Addition of a render endpoint

What I need is an endpoint that does the same as the "merge" endpoint (not do any converting / "touching" the raw data) and just accept the stream and create a PDF, but then, for a single PDF.

What I have done atm is "hack" the php-client and added a "render" method which removes the second and third argument (Stream $pdf2, Stream ...$pdfs) and just set the data for a single PDF and send it to the "merge" endpoint, and this works perfectly. But this feels very incorrect.

I'm just not fluent enough in Go to open a PR and help you guys with the Go side of things.
I wouldn't mind opening a PR to the php-client side though and maybe even make it more extensible (atm I had to copy the entire class because of concrete types and private properties in stead of interfaces and protected properties (e.g.)).

Upload Merged File to S3

How can we upload merged file to S3 without storing it to local storage.
Here is my code.

`$array=[Stream::path($file_name),Stream::path($file_name),Stream::path($file_name)];

$request = Gotenberg::libreOffice("https://demo.gotenberg.dev")
->outputFilename('merged')
->merge()
->convert(...$array)`

[Support] GuzzleHttp\Psr7\Stream vs Gotenberg\Stream

Greetings!

I am sorry to pollute your ticket stream with a support request. 😞

✅ I have successfully implemented the gotenberg (v7) docker image and this library into my Symfony-based project.
✅ I have successfully "merged" its use with FlySystem via the OneupFlysystemBundle
✅ I am successfully producing merged pdfs from sources of html & office docs and storing them to AWS/S3 via the AwsS3 Flysystem adapter!

So all, in all, I am quite happy with the end product. I have one kludgy bit however, which I wondered if you might assist me.

Flysystem works well with Streams. But not directly with your Stream class. Therefore I end up doing something like this several times in my project:

    use Gotenberg\Stream;
    use GuzzleHttp\Psr7\Stream as Psr7Stream;

        ....

        $streams = [];
        foreach ($mountPaths as $mountPath) {
            $psr7Stream = new Psr7Stream($this->mountManager->readStream($mountPath));
            $streams[] = new Stream('file.pdf', $psr7Stream);
        }
        $request = $this->gotenberg->pdfEngines()
            ->outputFilename($destination)
            ->merge(...$streams);

(my gotenberg instance above is simply a wrapper of yours in order to include other services with DI)

You can see the gymnastics I am doing to first create the Psr7Stream (readStream returns a resource), then secondly create an instead of Stream.

Is there a cleaner way to do this? Can I create a Gotenberg/Stream directly from a resource or handle this differently?

Secondly, I'd like to write a stream directly from the response. Currently I do this:

        $response = $this->send($request, $client);
        ...
        $this->mountManager->write($mountPath.$filename, $response->getBody()->getContents());

I'd prefer to use Flysystem's writeStream method here if possible, Is it possible to get a Stream from the response?


As I said, I apologize in advance for the support request. I'm sure you're rolling your eyes at my stupidity 🙄 🤣 . Thanks in advance! 🙇

Laravel 8

Does it works with Laravel 8?

I tried to install and use it, but I got the error below:

TypeError
Symfony\Component\HttpFoundation\Response::setContent(): Argument #1 ($content) must be of type ?string, Nyholm\Psr7\Request given, called in ../vendor/laravel/framework/src/Illuminate/Http/Response.php on line 72 

Merge of long urls pointing to PDFs failing

I have a situation where I have files sitting in an S3/GCS bucket and need to merge certain files from that bucket. Since cloud storage isn't treated the same as local storage by gotenberg, we use temporary URLs from the bucket to merge certain files together. These temporary URLs are very long (sometimes 400+ characters) and this seems to cause an error with the gotenberg API.

    $streams = collect($long_urls)->map(
        fn($long_url) => Stream::path($long_url)
    );

    $request = Gotenberg::pdfEngines($apiUrl)
        ->outputFilename('requested-name')
        ->merge(
            ...$streams
        );

When I run this code with the long urls, I get a Gotenberg\Exceptions\GotenbergApiErroed error and if I check the gotenberg docker container, it says

{
   "level":"error",
   "ts":1641567947.0926168,
   "logger":"api",
   "msg":"create request context: copy to disk: create local file: open /tmp/aabf345b-68eb-457a-bbcb-728cc3813e1f/0_2021%20AR%20Help%20Manual%2010-27-2021.pdf?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAQPF2CX2ONHXT3XG3%2F20220107%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220107T150546Z&X-Amz-SignedHeaders=host&X-Amz-Expires=300&X-Amz-Signature=75620efd0a5e1c3520c398d50ea51c434b200e9785d830ddc350c14dbe714b4a: file name too long",
   "trace":"2aa4913a-534a-41af-911b-90296e43adc7",
   "remote_ip":"172.18.0.8",
   "host":"gotenberg:3000",
   "uri":"/forms/pdfengines/merge",
   "method":"POST",
   "path":"/forms/pdfengines/merge",
   "referer":"",
   "user_agent":"Symfony HttpClient/Curl",
   "status":500,
   "latency":5535083,
   "latency_human":"5.535083ms",
   "bytes_in":3083724,
   "bytes_out":21
}

I'm not sure if this is because of code changes between gotenberg/gotenberg 6 => 7 or from thecodingmachine/gotenberg => gotenberg/gotenberg-php but was wondering if I could get some help.

Content of ->html(Stream::string('index.html', $html)) is not added to PDF when header and/or footer are added to each page of the PDF

If I add a header and/or footer to each page of the PDF, the main content between header and footer is missing
when using the string() method of Stream class:
->html(Stream::string('index.html', $html));

If I use the path() method of the Stream class instead, it works:
->html(Stream::path('/var/www/html/public/test.html'));

When I comment out header() and footer() chained methods,
->html(Stream::string('index.html', $html));
is also working.

Is this a bug or am I missing something?

This is my test script:

<?php

use Gotenberg\Gotenberg;
use Gotenberg\Stream;

require_once "vendor/autoload.php";

//$html = file_get_contents('/var/www/html/public/test.html');

$chromium = Gotenberg::chromium('http://gotenberg:3000')
    //->pdf() // uncomment for gotenberg/gotenberg-php ^2.0; Same results on version 2.0.0
    ->header(Stream::path('http://nginx:80/header/de'))
    ->footer(Stream::path('http://nginx:80/footer/de'))


    // With this, main content will not be printed to PDF if header() and/or footer() are also chained;
    // If header() and footer() are commented out, main content is printed correctly to PDF
    //->html(Stream::string('index.html', $html));


    // with this, main content is ALWAYS printed correctly to PDF
    ->html(Stream::path('/var/www/html/public/test.html'));

$response = Gotenberg::send($chromium);
file_put_contents('/var/www/html/public/test.pdf', $response->getBody()->getContents());

echo "done.\n";

Laravel 10 : need help

Hi,
I'm trying to print blade view using url, Stream
Url :

 $request = Gotenberg::chromium('http://gotenberg:3000')
                        ->pdf()
                        ->skipNetworkIdleEvent()
                        ->url(url('template4'));

I get a blank pdf page, while if I use other url like google.com, it works fine.
NB: I can access to url('template4').

Stream :

$inv = view('print.sales.templates.4.main')->render();

                    $request = Gotenberg::chromium('http://gotenberg:3000')
                        ->pdf()
                        ->html(Stream::string('my.html', $inv));

It works but without CSS !! (I'm using boostrap css)

What am I missing ?

unexpected 'array' (T_ARRAY), expecting function (T_FUNCTION) or const (T_CONST) in MultipartFormDataModule.php on line 20

Hi,

I've tried to convert an HTML page into a PDF but I already got the same error:

"unexpected 'array' (T_ARRAY), expecting function (T_FUNCTION) or const (T_CONST) in MultipartFormDataModule.php on line 20"

and i don't understand why.

Here is my PHP code:

  <?php
    require 'vendor/autoload.php';
    use Gotenberg\Gotenberg;
    use Gotenberg\Stream;
    $apiUrl = "http://localhost:3000";
    $request = Gotenberg::chromium($apiUrl)->html(Stream::path('etiquette.html'));
    ?>

I've tried with other method as:

use Gotenberg\Gotenberg;

   // Converts a target URL to PDF and saves it to a given directory.
    $filename = Gotenberg::save(
    Gotenberg::chromium($apiUrl)->url('https://my.url'), 
    $pathToSavingDirectory
);

but I've got the same result.

Have you got any idea about why I've got this error please?

Thanks

Error when passing associative array to merge function

I'm getting an error when trying to pass an associative array to the merge call.

There are actually two errors I'm getting, the first happens when trying to pass it like normal with argument unpacking:

   $streams = array_map(
        fn($long_url) => Stream::path($long_url),
        $keyed_array_of_urls
    );

    $request = Gotenberg::pdfEngines($apiUrl)
        ->outputFilename('requested-name')
        ->merge(
            ...$streams
        );

The error I get is: Too few arguments to function Gotenberg\Modules\PdfEngines::merge(), 0 passed

So to remedy that and match the function signature, I use array_shift() to match:

    $request = Gotenberg::pdfEngines($apiUrl)
        ->outputFilename('requested-name')
        ->merge(
            array_shift$streams),
            array_shift$streams),
            ...$streams
        );

This gives me the error message: Unsupported operand types: string + int from vendor/gotenberg/gotenberg-php/src/Modules/PdfEngines.php:41

I'm currently getting around this by simply using array_values() and not passing an associative array.

    $request = Gotenberg::pdfEngines($apiUrl)
        ->outputFilename('requested-name')
        ->merge(
            ...array_values($streams)
        );

Just thought it might be worth bringing to your attention. Thanks for all the hard work!

Wrong merge order if > 26 files

refs #9

your Index class produces something like

A B C D E F ... AA AB AC ...

except when sorting, AB comes before B, so it is sorted wrongly.

I recommend deleting your Index class and using something like this (untested):

    public function merge(Stream $pdf1, Stream $pdf2, Stream ...$pdfs): RequestInterface
    {
        foreach ([$pdf1, $pdf2, ...$pdfs] as $pdf) {
            $this->formFile(hrtime(true) . '_' . $pdf->getFilename(), $pdf->getStream());
        }

        $this->endpoint = '/forms/pdfengines/merge';

        return $this->request();
    }

Disable Footer entirely rather than show the temporary filename?

If there is an empty footer or header I would expect it to be empty. What is happening here?

To resolve issues like puppeteer/puppeteer#2089 we need to generate separate PDF:s and then merge. Some pages should not have footer or header, while others should.

        $this->gotenbergChromium = Gotenberg::chromium($this->baseUri)
            // No margins, but many pages will define using @page css rules
            ->margins(0, 0, 0, 0)
            // A4 in inches
            ->paperSize(8.275, 11.7)
            ->preferCssPageSize()
            ->printBackground();

Then later:

        foreach ($documents as $document) {
            if ($document->showFooter()) {
                $this->gotenbergChromium->footer(
                    Stream::string('footer.html', $document->renderFooterHtml())
                );
            } else {
                $this->gotenbergChromium->footer(
                    Stream::string('footer.html', '')
                );
            }

            // Add main content
            // Save PDF content
            // Merge multiple pages
        }

Result:
image

Request times out, while testing locally

My Php code
$request = Gotenberg::chromium('http://127.0.0.1:3000') ->url("http://host.docker.internal:8000/invoice/view");
$response = Gotenberg::send($request);
OS is ubuntu 22.
Docker container was started using docker run --rm --add-host host.docker.internal:host-gateway -p 3000:3000 gotenberg/gotenberg:7

Was able to successfully curl from within the docker instance by following the commands
docker exec -it <hash> bash; curl "http://host.docker.internal:8001/invoice/view"

Docker logs
"
{"level":"error","ts":1704128572.4625182,"logger":"api","msg":"convert URL to PDF: convert to PDF: context deadline exceeded","trace":"ba64d68d-0eb2-4834-831a-8db4d8415904","remote_ip":"172.17.0.1","host":"127.0.0.1:3000","uri":"/forms/chromium/convert/url","method":"POST","path":"/forms/chromium/convert/url","referer":"","user_agent":"GuzzleHttp/7","status":503,"latency":30001594641,"latency_human":"30.001594641s","bytes_in":203,"bytes_out":19}
"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.