feat: add Go, PHP, and Laravel SDKs
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
- Go SDK: zero deps, functional options pattern, full endpoint coverage - PHP SDK: PHP 8.1+, curl-based, PdfOptions class, PSR-4 autoloading - Laravel package: ServiceProvider, Facade, config publishing - All SDKs document complete PDF options including new v0.4.5 params
This commit is contained in:
parent
1545df9a7b
commit
bc67c52d3a
13 changed files with 1133 additions and 0 deletions
151
sdk/go/README.md
Normal file
151
sdk/go/README.md
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
# DocFast Go SDK
|
||||||
|
|
||||||
|
Official Go client for the [DocFast](https://docfast.dev) HTML/Markdown to PDF API.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go get github.com/docfast/docfast-go
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
docfast "github.com/docfast/docfast-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
client := docfast.New("df_pro_your_api_key")
|
||||||
|
|
||||||
|
// HTML to PDF
|
||||||
|
pdf, err := client.HTML("<h1>Hello World</h1><p>Generated with DocFast</p>", nil)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
os.WriteFile("output.pdf", pdf, 0644)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### HTML to PDF
|
||||||
|
|
||||||
|
```go
|
||||||
|
pdf, err := client.HTML("<h1>Hello</h1>", &docfast.PDFOptions{
|
||||||
|
Format: "A4",
|
||||||
|
Landscape: true,
|
||||||
|
Margin: &docfast.Margin{Top: "20mm", Bottom: "20mm"},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### HTML with custom CSS
|
||||||
|
|
||||||
|
```go
|
||||||
|
pdf, err := client.HTMLWithCSS(
|
||||||
|
"<h1>Styled</h1>",
|
||||||
|
"h1 { color: navy; font-family: Georgia; }",
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Markdown to PDF
|
||||||
|
|
||||||
|
```go
|
||||||
|
pdf, err := client.Markdown("# Report\n\nGenerated **automatically**.", nil)
|
||||||
|
```
|
||||||
|
|
||||||
|
### URL to PDF
|
||||||
|
|
||||||
|
```go
|
||||||
|
pdf, err := client.URL("https://example.com", &docfast.PDFOptions{
|
||||||
|
Format: "Letter",
|
||||||
|
PrintBackground: docfast.Bool(true),
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Headers and Footers
|
||||||
|
|
||||||
|
```go
|
||||||
|
pdf, err := client.HTML(html, &docfast.PDFOptions{
|
||||||
|
DisplayHeaderFooter: true,
|
||||||
|
HeaderTemplate: `<div style="font-size:10px;text-align:center;width:100%">My Document</div>`,
|
||||||
|
FooterTemplate: `<div style="font-size:10px;text-align:center;width:100%">Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>`,
|
||||||
|
Margin: &docfast.Margin{Top: "40mm", Bottom: "20mm"},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom Page Size
|
||||||
|
|
||||||
|
```go
|
||||||
|
pdf, err := client.HTML(html, &docfast.PDFOptions{
|
||||||
|
Width: "8.5in",
|
||||||
|
Height: "11in",
|
||||||
|
Scale: 0.8,
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Templates
|
||||||
|
|
||||||
|
```go
|
||||||
|
// List available templates
|
||||||
|
templates, err := client.Templates()
|
||||||
|
|
||||||
|
// Render a template
|
||||||
|
pdf, err := client.RenderTemplate("invoice", map[string]interface{}{
|
||||||
|
"company": "Acme Corp",
|
||||||
|
"items": []map[string]interface{}{{"name": "Widget", "price": 9.99}},
|
||||||
|
"_format": "A4",
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## PDF Options
|
||||||
|
|
||||||
|
| Option | Type | Default | Description |
|
||||||
|
|--------|------|---------|-------------|
|
||||||
|
| `Format` | string | `"A4"` | Page size: A4, Letter, Legal, A3, A5, Tabloid |
|
||||||
|
| `Landscape` | bool | `false` | Landscape orientation |
|
||||||
|
| `Margin` | *Margin | `nil` | Page margins (CSS units) |
|
||||||
|
| `PrintBackground` | *bool | `true` | Print background graphics |
|
||||||
|
| `Filename` | string | `""` | Suggested filename |
|
||||||
|
| `HeaderTemplate` | string | `""` | HTML header template |
|
||||||
|
| `FooterTemplate` | string | `""` | HTML footer template |
|
||||||
|
| `DisplayHeaderFooter` | bool | `false` | Show header/footer |
|
||||||
|
| `Scale` | float64 | `1` | Rendering scale (0.1–2.0) |
|
||||||
|
| `PageRanges` | string | `""` | Pages to print (e.g. "1-3,5") |
|
||||||
|
| `PreferCSSPageSize` | bool | `false` | Prefer CSS @page size |
|
||||||
|
| `Width` | string | `""` | Custom paper width |
|
||||||
|
| `Height` | string | `""` | Custom paper height |
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
```go
|
||||||
|
pdf, err := client.HTML("<h1>Test</h1>", nil)
|
||||||
|
if err != nil {
|
||||||
|
var apiErr *docfast.Error
|
||||||
|
if errors.As(err, &apiErr) {
|
||||||
|
fmt.Printf("API error: %s (status %d)\n", apiErr.Message, apiErr.StatusCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Custom base URL (e.g. for self-hosted or staging)
|
||||||
|
client := docfast.New("key", docfast.WithBaseURL("https://staging.docfast.dev"))
|
||||||
|
|
||||||
|
// Custom HTTP client
|
||||||
|
client := docfast.New("key", docfast.WithHTTPClient(&http.Client{
|
||||||
|
Timeout: 120 * time.Second,
|
||||||
|
}))
|
||||||
|
```
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
- [Documentation](https://docfast.dev/docs)
|
||||||
|
- [API Reference](https://docfast.dev/openapi.json)
|
||||||
|
- [Get an API Key](https://docfast.dev)
|
||||||
293
sdk/go/docfast.go
Normal file
293
sdk/go/docfast.go
Normal file
|
|
@ -0,0 +1,293 @@
|
||||||
|
// Package docfast provides a Go client for the DocFast HTML/Markdown to PDF API.
|
||||||
|
//
|
||||||
|
// Usage:
|
||||||
|
//
|
||||||
|
// client := docfast.New("df_pro_your_key")
|
||||||
|
// pdf, err := client.HTML("<h1>Hello</h1>", nil)
|
||||||
|
package docfast
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const defaultBaseURL = "https://docfast.dev"
|
||||||
|
|
||||||
|
// Margin defines PDF page margins using CSS units (e.g. "20mm", "1in").
|
||||||
|
type Margin struct {
|
||||||
|
Top string `json:"top,omitempty"`
|
||||||
|
Bottom string `json:"bottom,omitempty"`
|
||||||
|
Left string `json:"left,omitempty"`
|
||||||
|
Right string `json:"right,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PDFOptions configures PDF generation. All fields are optional.
|
||||||
|
type PDFOptions struct {
|
||||||
|
// Page size: A4, Letter, Legal, A3, A5, Tabloid. Ignored if Width/Height set.
|
||||||
|
Format string `json:"format,omitempty"`
|
||||||
|
// Landscape orientation.
|
||||||
|
Landscape bool `json:"landscape,omitempty"`
|
||||||
|
// Page margins.
|
||||||
|
Margin *Margin `json:"margin,omitempty"`
|
||||||
|
// Print background graphics and colors. Default: true.
|
||||||
|
PrintBackground *bool `json:"printBackground,omitempty"`
|
||||||
|
// Suggested filename for the PDF download.
|
||||||
|
Filename string `json:"filename,omitempty"`
|
||||||
|
// HTML template for page header. Requires DisplayHeaderFooter: true.
|
||||||
|
// Supports CSS classes: date, title, url, pageNumber, totalPages.
|
||||||
|
HeaderTemplate string `json:"headerTemplate,omitempty"`
|
||||||
|
// HTML template for page footer. Same classes as HeaderTemplate.
|
||||||
|
FooterTemplate string `json:"footerTemplate,omitempty"`
|
||||||
|
// Show header and footer templates.
|
||||||
|
DisplayHeaderFooter bool `json:"displayHeaderFooter,omitempty"`
|
||||||
|
// Scale of webpage rendering (0.1 to 2.0). Default: 1.
|
||||||
|
Scale float64 `json:"scale,omitempty"`
|
||||||
|
// Paper ranges to print, e.g. "1-3,5".
|
||||||
|
PageRanges string `json:"pageRanges,omitempty"`
|
||||||
|
// Give CSS @page size priority over Format.
|
||||||
|
PreferCSSPageSize bool `json:"preferCSSPageSize,omitempty"`
|
||||||
|
// Paper width with units (e.g. "8.5in"). Overrides Format.
|
||||||
|
Width string `json:"width,omitempty"`
|
||||||
|
// Paper height with units (e.g. "11in"). Overrides Format.
|
||||||
|
Height string `json:"height,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Template describes an available PDF template.
|
||||||
|
type Template struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error is returned when the API responds with an error.
|
||||||
|
type Error struct {
|
||||||
|
StatusCode int
|
||||||
|
Message string
|
||||||
|
Code string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Error) Error() string {
|
||||||
|
if e.Code != "" {
|
||||||
|
return fmt.Sprintf("docfast: %s (code=%s, status=%d)", e.Message, e.Code, e.StatusCode)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("docfast: %s (status=%d)", e.Message, e.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientOption configures the Client.
|
||||||
|
type ClientOption func(*Client)
|
||||||
|
|
||||||
|
// WithBaseURL sets a custom API base URL.
|
||||||
|
func WithBaseURL(url string) ClientOption {
|
||||||
|
return func(c *Client) { c.baseURL = url }
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithHTTPClient sets a custom http.Client.
|
||||||
|
func WithHTTPClient(hc *http.Client) ClientOption {
|
||||||
|
return func(c *Client) { c.httpClient = hc }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client is the DocFast API client.
|
||||||
|
type Client struct {
|
||||||
|
apiKey string
|
||||||
|
baseURL string
|
||||||
|
httpClient *http.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a new DocFast client.
|
||||||
|
func New(apiKey string, opts ...ClientOption) *Client {
|
||||||
|
c := &Client{
|
||||||
|
apiKey: apiKey,
|
||||||
|
baseURL: defaultBaseURL,
|
||||||
|
httpClient: &http.Client{
|
||||||
|
Timeout: 60 * time.Second,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, o := range opts {
|
||||||
|
o(c)
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) post(path string, body map[string]interface{}) ([]byte, error) {
|
||||||
|
data, err := json.Marshal(body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("docfast: marshal error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", c.baseURL+path, bytes.NewReader(data))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("docfast: request error: %w", err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Authorization", "Bearer "+c.apiKey)
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := c.httpClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("docfast: request failed: %w", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
respBody, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("docfast: read error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode >= 400 {
|
||||||
|
apiErr := &Error{StatusCode: resp.StatusCode, Message: fmt.Sprintf("HTTP %d", resp.StatusCode)}
|
||||||
|
var errResp struct {
|
||||||
|
Error string `json:"error"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
}
|
||||||
|
if json.Unmarshal(respBody, &errResp) == nil {
|
||||||
|
if errResp.Error != "" {
|
||||||
|
apiErr.Message = errResp.Error
|
||||||
|
}
|
||||||
|
apiErr.Code = errResp.Code
|
||||||
|
}
|
||||||
|
return nil, apiErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return respBody, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) get(path string) ([]byte, error) {
|
||||||
|
req, err := http.NewRequest("GET", c.baseURL+path, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("docfast: request error: %w", err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Authorization", "Bearer "+c.apiKey)
|
||||||
|
|
||||||
|
resp, err := c.httpClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("docfast: request failed: %w", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
respBody, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("docfast: read error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode >= 400 {
|
||||||
|
apiErr := &Error{StatusCode: resp.StatusCode, Message: fmt.Sprintf("HTTP %d", resp.StatusCode)}
|
||||||
|
var errResp struct {
|
||||||
|
Error string `json:"error"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
}
|
||||||
|
if json.Unmarshal(respBody, &errResp) == nil && errResp.Error != "" {
|
||||||
|
apiErr.Message = errResp.Error
|
||||||
|
apiErr.Code = errResp.Code
|
||||||
|
}
|
||||||
|
return nil, apiErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return respBody, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func mergeOptions(body map[string]interface{}, opts *PDFOptions) {
|
||||||
|
if opts == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if opts.Format != "" {
|
||||||
|
body["format"] = opts.Format
|
||||||
|
}
|
||||||
|
if opts.Landscape {
|
||||||
|
body["landscape"] = true
|
||||||
|
}
|
||||||
|
if opts.Margin != nil {
|
||||||
|
body["margin"] = opts.Margin
|
||||||
|
}
|
||||||
|
if opts.PrintBackground != nil {
|
||||||
|
body["printBackground"] = *opts.PrintBackground
|
||||||
|
}
|
||||||
|
if opts.Filename != "" {
|
||||||
|
body["filename"] = opts.Filename
|
||||||
|
}
|
||||||
|
if opts.HeaderTemplate != "" {
|
||||||
|
body["headerTemplate"] = opts.HeaderTemplate
|
||||||
|
}
|
||||||
|
if opts.FooterTemplate != "" {
|
||||||
|
body["footerTemplate"] = opts.FooterTemplate
|
||||||
|
}
|
||||||
|
if opts.DisplayHeaderFooter {
|
||||||
|
body["displayHeaderFooter"] = true
|
||||||
|
}
|
||||||
|
if opts.Scale != 0 {
|
||||||
|
body["scale"] = opts.Scale
|
||||||
|
}
|
||||||
|
if opts.PageRanges != "" {
|
||||||
|
body["pageRanges"] = opts.PageRanges
|
||||||
|
}
|
||||||
|
if opts.PreferCSSPageSize {
|
||||||
|
body["preferCSSPageSize"] = true
|
||||||
|
}
|
||||||
|
if opts.Width != "" {
|
||||||
|
body["width"] = opts.Width
|
||||||
|
}
|
||||||
|
if opts.Height != "" {
|
||||||
|
body["height"] = opts.Height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTML converts HTML content to PDF. Returns the raw PDF bytes.
|
||||||
|
func (c *Client) HTML(html string, opts *PDFOptions) ([]byte, error) {
|
||||||
|
body := map[string]interface{}{"html": html}
|
||||||
|
mergeOptions(body, opts)
|
||||||
|
return c.post("/v1/convert/html", body)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTMLWithCSS converts an HTML fragment with optional CSS to PDF.
|
||||||
|
func (c *Client) HTMLWithCSS(html, css string, opts *PDFOptions) ([]byte, error) {
|
||||||
|
body := map[string]interface{}{"html": html, "css": css}
|
||||||
|
mergeOptions(body, opts)
|
||||||
|
return c.post("/v1/convert/html", body)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Markdown converts Markdown content to PDF.
|
||||||
|
func (c *Client) Markdown(markdown string, opts *PDFOptions) ([]byte, error) {
|
||||||
|
body := map[string]interface{}{"markdown": markdown}
|
||||||
|
mergeOptions(body, opts)
|
||||||
|
return c.post("/v1/convert/markdown", body)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkdownWithCSS converts Markdown with optional CSS to PDF.
|
||||||
|
func (c *Client) MarkdownWithCSS(markdown, css string, opts *PDFOptions) ([]byte, error) {
|
||||||
|
body := map[string]interface{}{"markdown": markdown, "css": css}
|
||||||
|
mergeOptions(body, opts)
|
||||||
|
return c.post("/v1/convert/markdown", body)
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL converts a web page at the given URL to PDF.
|
||||||
|
func (c *Client) URL(url string, opts *PDFOptions) ([]byte, error) {
|
||||||
|
body := map[string]interface{}{"url": url}
|
||||||
|
mergeOptions(body, opts)
|
||||||
|
return c.post("/v1/convert/url", body)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Templates returns the list of available PDF templates.
|
||||||
|
func (c *Client) Templates() ([]Template, error) {
|
||||||
|
data, err := c.get("/v1/templates")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var result struct {
|
||||||
|
Templates []Template `json:"templates"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(data, &result); err != nil {
|
||||||
|
return nil, fmt.Errorf("docfast: decode error: %w", err)
|
||||||
|
}
|
||||||
|
return result.Templates, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RenderTemplate renders a template with the given data and returns PDF bytes.
|
||||||
|
func (c *Client) RenderTemplate(templateID string, data map[string]interface{}) ([]byte, error) {
|
||||||
|
body := map[string]interface{}{"data": data}
|
||||||
|
return c.post("/v1/templates/"+templateID, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool is a helper to create a *bool for PDFOptions.PrintBackground.
|
||||||
|
func Bool(v bool) *bool { return &v }
|
||||||
3
sdk/go/go.mod
Normal file
3
sdk/go/go.mod
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
module github.com/docfast/docfast-go
|
||||||
|
|
||||||
|
go 1.21
|
||||||
114
sdk/laravel/README.md
Normal file
114
sdk/laravel/README.md
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
# DocFast for Laravel
|
||||||
|
|
||||||
|
Official Laravel integration for the [DocFast](https://docfast.dev) HTML/Markdown to PDF API.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
composer require docfast/laravel
|
||||||
|
```
|
||||||
|
|
||||||
|
Add your API key to `.env`:
|
||||||
|
|
||||||
|
```env
|
||||||
|
DOCFAST_API_KEY=df_pro_your_api_key
|
||||||
|
```
|
||||||
|
|
||||||
|
Publish the config (optional):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php artisan vendor:publish --tag=docfast-config
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Via Facade
|
||||||
|
|
||||||
|
```php
|
||||||
|
use DocFast\Laravel\Facades\DocFast;
|
||||||
|
|
||||||
|
// HTML to PDF
|
||||||
|
$pdf = DocFast::html('<h1>Invoice</h1><p>Total: €99.00</p>');
|
||||||
|
return response($pdf)
|
||||||
|
->header('Content-Type', 'application/pdf')
|
||||||
|
->header('Content-Disposition', 'inline; filename="invoice.pdf"');
|
||||||
|
```
|
||||||
|
|
||||||
|
### Via Dependency Injection
|
||||||
|
|
||||||
|
```php
|
||||||
|
use DocFast\Client;
|
||||||
|
|
||||||
|
class InvoiceController extends Controller
|
||||||
|
{
|
||||||
|
public function download(Client $docfast)
|
||||||
|
{
|
||||||
|
$pdf = $docfast->html(view('invoice')->render());
|
||||||
|
return response($pdf)
|
||||||
|
->header('Content-Type', 'application/pdf');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Markdown to PDF
|
||||||
|
|
||||||
|
```php
|
||||||
|
$pdf = DocFast::markdown('# Report\n\nGenerated at ' . now());
|
||||||
|
```
|
||||||
|
|
||||||
|
### URL to PDF
|
||||||
|
|
||||||
|
```php
|
||||||
|
$pdf = DocFast::url('https://example.com');
|
||||||
|
```
|
||||||
|
|
||||||
|
### With PDF Options
|
||||||
|
|
||||||
|
```php
|
||||||
|
use DocFast\PdfOptions;
|
||||||
|
|
||||||
|
$options = new PdfOptions();
|
||||||
|
$options->format = 'Letter';
|
||||||
|
$options->landscape = true;
|
||||||
|
$options->margin = ['top' => '20mm', 'bottom' => '20mm'];
|
||||||
|
|
||||||
|
$pdf = DocFast::html($html, null, $options);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Headers and Footers
|
||||||
|
|
||||||
|
```php
|
||||||
|
$options = new PdfOptions();
|
||||||
|
$options->displayHeaderFooter = true;
|
||||||
|
$options->footerTemplate = '<div style="font-size:9px;text-align:center;width:100%">Page <span class="pageNumber"></span></div>';
|
||||||
|
$options->margin = ['top' => '10mm', 'bottom' => '20mm'];
|
||||||
|
|
||||||
|
$pdf = DocFast::html(view('report')->render(), null, $options);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Templates
|
||||||
|
|
||||||
|
```php
|
||||||
|
$pdf = DocFast::renderTemplate('invoice', [
|
||||||
|
'company' => 'Acme Corp',
|
||||||
|
'items' => [['name' => 'Widget', 'price' => 9.99]],
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
```php
|
||||||
|
// config/docfast.php
|
||||||
|
return [
|
||||||
|
'api_key' => env('DOCFAST_API_KEY'),
|
||||||
|
'base_url' => env('DOCFAST_BASE_URL', 'https://docfast.dev'),
|
||||||
|
'timeout' => env('DOCFAST_TIMEOUT', 60),
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
- [PHP SDK](../php/) — standalone PHP client
|
||||||
|
- [Documentation](https://docfast.dev/docs)
|
||||||
|
- [API Reference](https://docfast.dev/openapi.json)
|
||||||
|
- [Get an API Key](https://docfast.dev)
|
||||||
34
sdk/laravel/composer.json
Normal file
34
sdk/laravel/composer.json
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"name": "docfast/laravel",
|
||||||
|
"description": "Laravel integration for the DocFast HTML/Markdown to PDF API",
|
||||||
|
"type": "library",
|
||||||
|
"license": "MIT",
|
||||||
|
"homepage": "https://docfast.dev",
|
||||||
|
"keywords": ["pdf", "html-to-pdf", "laravel", "docfast"],
|
||||||
|
"require": {
|
||||||
|
"php": "^8.1",
|
||||||
|
"illuminate/support": "^10.0|^11.0|^12.0",
|
||||||
|
"docfast/docfast-php": "^1.0"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"DocFast\\Laravel\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"DocFast\\Laravel\\DocFastServiceProvider"
|
||||||
|
],
|
||||||
|
"aliases": {
|
||||||
|
"DocFast": "DocFast\\Laravel\\Facades\\DocFast"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "DocFast",
|
||||||
|
"homepage": "https://docfast.dev"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
33
sdk/laravel/config/docfast.php
Normal file
33
sdk/laravel/config/docfast.php
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| DocFast API Key
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Your DocFast Pro API key. Get one at https://docfast.dev
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
'api_key' => env('DOCFAST_API_KEY'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Base URL
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The DocFast API base URL. Change for staging or self-hosted instances.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
'base_url' => env('DOCFAST_BASE_URL', 'https://docfast.dev'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Timeout
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Request timeout in seconds for PDF generation.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
'timeout' => env('DOCFAST_TIMEOUT', 60),
|
||||||
|
];
|
||||||
34
sdk/laravel/src/DocFastServiceProvider.php
Normal file
34
sdk/laravel/src/DocFastServiceProvider.php
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DocFast\Laravel;
|
||||||
|
|
||||||
|
use DocFast\Client;
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
|
class DocFastServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
public function register(): void
|
||||||
|
{
|
||||||
|
$this->mergeConfigFrom(__DIR__ . '/../config/docfast.php', 'docfast');
|
||||||
|
|
||||||
|
$this->app->singleton(Client::class, function ($app) {
|
||||||
|
$config = $app['config']['docfast'];
|
||||||
|
return new Client(
|
||||||
|
$config['api_key'] ?? '',
|
||||||
|
$config['base_url'] ?? 'https://docfast.dev',
|
||||||
|
$config['timeout'] ?? 60,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->app->alias(Client::class, 'docfast');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function boot(): void
|
||||||
|
{
|
||||||
|
$this->publishes([
|
||||||
|
__DIR__ . '/../config/docfast.php' => config_path('docfast.php'),
|
||||||
|
], 'docfast-config');
|
||||||
|
}
|
||||||
|
}
|
||||||
25
sdk/laravel/src/Facades/DocFast.php
Normal file
25
sdk/laravel/src/Facades/DocFast.php
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DocFast\Laravel\Facades;
|
||||||
|
|
||||||
|
use DocFast\Client;
|
||||||
|
use Illuminate\Support\Facades\Facade;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method static string html(string $html, ?string $css = null, ?\DocFast\PdfOptions $options = null)
|
||||||
|
* @method static string markdown(string $markdown, ?string $css = null, ?\DocFast\PdfOptions $options = null)
|
||||||
|
* @method static string url(string $url, ?\DocFast\PdfOptions $options = null)
|
||||||
|
* @method static array templates()
|
||||||
|
* @method static string renderTemplate(string $templateId, array $data = [])
|
||||||
|
*
|
||||||
|
* @see \DocFast\Client
|
||||||
|
*/
|
||||||
|
class DocFast extends Facade
|
||||||
|
{
|
||||||
|
protected static function getFacadeAccessor(): string
|
||||||
|
{
|
||||||
|
return Client::class;
|
||||||
|
}
|
||||||
|
}
|
||||||
156
sdk/php/README.md
Normal file
156
sdk/php/README.md
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
# DocFast PHP SDK
|
||||||
|
|
||||||
|
Official PHP client for the [DocFast](https://docfast.dev) HTML/Markdown to PDF API.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- PHP 8.1+
|
||||||
|
- ext-curl
|
||||||
|
- ext-json
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
composer require docfast/docfast-php
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
```php
|
||||||
|
use DocFast\Client;
|
||||||
|
|
||||||
|
$client = new Client('df_pro_your_api_key');
|
||||||
|
|
||||||
|
// HTML to PDF
|
||||||
|
$pdf = $client->html('<h1>Hello World</h1>');
|
||||||
|
file_put_contents('output.pdf', $pdf);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### HTML to PDF
|
||||||
|
|
||||||
|
```php
|
||||||
|
$pdf = $client->html('<h1>Hello</h1><p>My document</p>');
|
||||||
|
```
|
||||||
|
|
||||||
|
### HTML with CSS
|
||||||
|
|
||||||
|
```php
|
||||||
|
$pdf = $client->html(
|
||||||
|
'<h1>Styled</h1>',
|
||||||
|
'h1 { color: navy; font-family: Georgia; }'
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### HTML with PDF Options
|
||||||
|
|
||||||
|
```php
|
||||||
|
use DocFast\PdfOptions;
|
||||||
|
|
||||||
|
$options = new PdfOptions();
|
||||||
|
$options->format = 'Letter';
|
||||||
|
$options->landscape = true;
|
||||||
|
$options->margin = ['top' => '20mm', 'bottom' => '20mm', 'left' => '15mm', 'right' => '15mm'];
|
||||||
|
$options->printBackground = true;
|
||||||
|
|
||||||
|
$pdf = $client->html('<h1>Report</h1>', null, $options);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Markdown to PDF
|
||||||
|
|
||||||
|
```php
|
||||||
|
$pdf = $client->markdown('# Hello World\n\nThis is **bold** text.');
|
||||||
|
```
|
||||||
|
|
||||||
|
### URL to PDF
|
||||||
|
|
||||||
|
```php
|
||||||
|
$pdf = $client->url('https://example.com');
|
||||||
|
```
|
||||||
|
|
||||||
|
### Headers and Footers
|
||||||
|
|
||||||
|
```php
|
||||||
|
$options = new PdfOptions();
|
||||||
|
$options->displayHeaderFooter = true;
|
||||||
|
$options->headerTemplate = '<div style="font-size:10px;text-align:center;width:100%">My Document</div>';
|
||||||
|
$options->footerTemplate = '<div style="font-size:10px;text-align:center;width:100%">Page <span class="pageNumber"></span>/<span class="totalPages"></span></div>';
|
||||||
|
$options->margin = ['top' => '40mm', 'bottom' => '20mm'];
|
||||||
|
|
||||||
|
$pdf = $client->html($html, null, $options);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom Page Size
|
||||||
|
|
||||||
|
```php
|
||||||
|
$options = new PdfOptions();
|
||||||
|
$options->width = '8.5in';
|
||||||
|
$options->height = '11in';
|
||||||
|
$options->scale = 0.8;
|
||||||
|
|
||||||
|
$pdf = $client->html($html, null, $options);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Templates
|
||||||
|
|
||||||
|
```php
|
||||||
|
// List templates
|
||||||
|
$templates = $client->templates();
|
||||||
|
|
||||||
|
// Render a template
|
||||||
|
$pdf = $client->renderTemplate('invoice', [
|
||||||
|
'company' => 'Acme Corp',
|
||||||
|
'items' => [['name' => 'Widget', 'price' => 9.99]],
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
## PDF Options
|
||||||
|
|
||||||
|
| Option | Type | Default | Description |
|
||||||
|
|--------|------|---------|-------------|
|
||||||
|
| `format` | string | `"A4"` | Page size: A4, Letter, Legal, A3, A5, Tabloid |
|
||||||
|
| `landscape` | bool | `false` | Landscape orientation |
|
||||||
|
| `margin` | array | `null` | Margins with top/bottom/left/right keys (CSS units) |
|
||||||
|
| `printBackground` | bool | `true` | Print background graphics |
|
||||||
|
| `filename` | string | `null` | Suggested filename |
|
||||||
|
| `headerTemplate` | string | `null` | HTML header template |
|
||||||
|
| `footerTemplate` | string | `null` | HTML footer template |
|
||||||
|
| `displayHeaderFooter` | bool | `false` | Show header/footer |
|
||||||
|
| `scale` | float | `1` | Rendering scale (0.1–2.0) |
|
||||||
|
| `pageRanges` | string | `null` | Pages to print (e.g. "1-3,5") |
|
||||||
|
| `preferCSSPageSize` | bool | `false` | Prefer CSS @page size |
|
||||||
|
| `width` | string | `null` | Custom paper width |
|
||||||
|
| `height` | string | `null` | Custom paper height |
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
```php
|
||||||
|
use DocFast\DocFastException;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdf = $client->html('<h1>Test</h1>');
|
||||||
|
} catch (DocFastException $e) {
|
||||||
|
echo "Error: {$e->getMessage()} (status: {$e->statusCode})\n";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
```php
|
||||||
|
// Custom base URL
|
||||||
|
$client = new Client('key', 'https://staging.docfast.dev');
|
||||||
|
|
||||||
|
// Custom timeout (seconds)
|
||||||
|
$client = new Client('key', 'https://docfast.dev', 120);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Laravel Integration
|
||||||
|
|
||||||
|
See the [DocFast Laravel package](../laravel/) for a dedicated Laravel integration with facades, config, and service provider.
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
- [Documentation](https://docfast.dev/docs)
|
||||||
|
- [API Reference](https://docfast.dev/openapi.json)
|
||||||
|
- [Get an API Key](https://docfast.dev)
|
||||||
24
sdk/php/composer.json
Normal file
24
sdk/php/composer.json
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"name": "docfast/docfast-php",
|
||||||
|
"description": "Official PHP SDK for the DocFast HTML/Markdown to PDF API",
|
||||||
|
"type": "library",
|
||||||
|
"license": "MIT",
|
||||||
|
"homepage": "https://docfast.dev",
|
||||||
|
"keywords": ["pdf", "html-to-pdf", "markdown-to-pdf", "api", "docfast"],
|
||||||
|
"require": {
|
||||||
|
"php": "^8.1",
|
||||||
|
"ext-json": "*",
|
||||||
|
"ext-curl": "*"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"DocFast\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "DocFast",
|
||||||
|
"homepage": "https://docfast.dev"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
183
sdk/php/src/Client.php
Normal file
183
sdk/php/src/Client.php
Normal file
|
|
@ -0,0 +1,183 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DocFast;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DocFast API client for HTML/Markdown to PDF conversion.
|
||||||
|
*
|
||||||
|
* @see https://docfast.dev/docs
|
||||||
|
*/
|
||||||
|
class Client
|
||||||
|
{
|
||||||
|
private string $apiKey;
|
||||||
|
private string $baseUrl;
|
||||||
|
private int $timeout;
|
||||||
|
|
||||||
|
public function __construct(string $apiKey, string $baseUrl = 'https://docfast.dev', int $timeout = 60)
|
||||||
|
{
|
||||||
|
if (empty($apiKey)) {
|
||||||
|
throw new \InvalidArgumentException('API key is required');
|
||||||
|
}
|
||||||
|
$this->apiKey = $apiKey;
|
||||||
|
$this->baseUrl = rtrim($baseUrl, '/');
|
||||||
|
$this->timeout = $timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert HTML to PDF.
|
||||||
|
*
|
||||||
|
* @param string $html HTML content
|
||||||
|
* @param string|null $css Optional CSS to inject
|
||||||
|
* @param PdfOptions|null $options PDF options
|
||||||
|
* @return string Raw PDF bytes
|
||||||
|
* @throws DocFastException
|
||||||
|
*/
|
||||||
|
public function html(string $html, ?string $css = null, ?PdfOptions $options = null): string
|
||||||
|
{
|
||||||
|
$body = ['html' => $html];
|
||||||
|
if ($css !== null) {
|
||||||
|
$body['css'] = $css;
|
||||||
|
}
|
||||||
|
return $this->convert('/v1/convert/html', $body, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert Markdown to PDF.
|
||||||
|
*
|
||||||
|
* @param string $markdown Markdown content
|
||||||
|
* @param string|null $css Optional CSS to inject
|
||||||
|
* @param PdfOptions|null $options PDF options
|
||||||
|
* @return string Raw PDF bytes
|
||||||
|
* @throws DocFastException
|
||||||
|
*/
|
||||||
|
public function markdown(string $markdown, ?string $css = null, ?PdfOptions $options = null): string
|
||||||
|
{
|
||||||
|
$body = ['markdown' => $markdown];
|
||||||
|
if ($css !== null) {
|
||||||
|
$body['css'] = $css;
|
||||||
|
}
|
||||||
|
return $this->convert('/v1/convert/markdown', $body, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a URL to PDF.
|
||||||
|
*
|
||||||
|
* @param string $url URL to convert
|
||||||
|
* @param PdfOptions|null $options PDF options
|
||||||
|
* @return string Raw PDF bytes
|
||||||
|
* @throws DocFastException
|
||||||
|
*/
|
||||||
|
public function url(string $url, ?PdfOptions $options = null): string
|
||||||
|
{
|
||||||
|
return $this->convert('/v1/convert/url', ['url' => $url], $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List available templates.
|
||||||
|
*
|
||||||
|
* @return array<array{id: string, name: string, description?: string}>
|
||||||
|
* @throws DocFastException
|
||||||
|
*/
|
||||||
|
public function templates(): array
|
||||||
|
{
|
||||||
|
$data = $this->get('/v1/templates');
|
||||||
|
$result = json_decode($data, true);
|
||||||
|
return $result['templates'] ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a template to PDF.
|
||||||
|
*
|
||||||
|
* @param string $templateId Template ID
|
||||||
|
* @param array $data Template data
|
||||||
|
* @return string Raw PDF bytes
|
||||||
|
* @throws DocFastException
|
||||||
|
*/
|
||||||
|
public function renderTemplate(string $templateId, array $data = []): string
|
||||||
|
{
|
||||||
|
return $this->post('/v1/templates/' . urlencode($templateId), ['data' => $data]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function convert(string $path, array $body, ?PdfOptions $options): string
|
||||||
|
{
|
||||||
|
if ($options !== null) {
|
||||||
|
$body = array_merge($body, $options->toArray());
|
||||||
|
}
|
||||||
|
return $this->post($path, $body);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function post(string $path, array $body): string
|
||||||
|
{
|
||||||
|
$ch = curl_init($this->baseUrl . $path);
|
||||||
|
curl_setopt_array($ch, [
|
||||||
|
CURLOPT_POST => true,
|
||||||
|
CURLOPT_POSTFIELDS => json_encode($body),
|
||||||
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
|
CURLOPT_TIMEOUT => $this->timeout,
|
||||||
|
CURLOPT_HTTPHEADER => [
|
||||||
|
'Authorization: Bearer ' . $this->apiKey,
|
||||||
|
'Content-Type: application/json',
|
||||||
|
'Accept: application/pdf',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
$error = curl_error($ch);
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
if ($response === false) {
|
||||||
|
throw new DocFastException('Request failed: ' . $error, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($statusCode >= 400) {
|
||||||
|
$this->handleError($response, $statusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function get(string $path): string
|
||||||
|
{
|
||||||
|
$ch = curl_init($this->baseUrl . $path);
|
||||||
|
curl_setopt_array($ch, [
|
||||||
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
|
CURLOPT_TIMEOUT => $this->timeout,
|
||||||
|
CURLOPT_HTTPHEADER => [
|
||||||
|
'Authorization: Bearer ' . $this->apiKey,
|
||||||
|
'Accept: application/json',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
$error = curl_error($ch);
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
if ($response === false) {
|
||||||
|
throw new DocFastException('Request failed: ' . $error, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($statusCode >= 400) {
|
||||||
|
$this->handleError($response, $statusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function handleError(string $response, int $statusCode): never
|
||||||
|
{
|
||||||
|
$message = "HTTP $statusCode";
|
||||||
|
$code = null;
|
||||||
|
|
||||||
|
$data = json_decode($response, true);
|
||||||
|
if (is_array($data)) {
|
||||||
|
$message = $data['error'] ?? $message;
|
||||||
|
$code = $data['code'] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new DocFastException($message, $statusCode, $code);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
sdk/php/src/DocFastException.php
Normal file
18
sdk/php/src/DocFastException.php
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DocFast;
|
||||||
|
|
||||||
|
class DocFastException extends \RuntimeException
|
||||||
|
{
|
||||||
|
public readonly int $statusCode;
|
||||||
|
public readonly ?string $errorCode;
|
||||||
|
|
||||||
|
public function __construct(string $message, int $statusCode, ?string $errorCode = null, ?\Throwable $previous = null)
|
||||||
|
{
|
||||||
|
$this->statusCode = $statusCode;
|
||||||
|
$this->errorCode = $errorCode;
|
||||||
|
parent::__construct($message, $statusCode, $previous);
|
||||||
|
}
|
||||||
|
}
|
||||||
65
sdk/php/src/PdfOptions.php
Normal file
65
sdk/php/src/PdfOptions.php
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DocFast;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PDF generation options.
|
||||||
|
*/
|
||||||
|
class PdfOptions
|
||||||
|
{
|
||||||
|
/** Page size: A4, Letter, Legal, A3, A5, Tabloid. Ignored if width/height set. */
|
||||||
|
public ?string $format = null;
|
||||||
|
|
||||||
|
/** Landscape orientation. */
|
||||||
|
public ?bool $landscape = null;
|
||||||
|
|
||||||
|
/** Page margins using CSS units (e.g. "20mm"). */
|
||||||
|
public ?array $margin = null;
|
||||||
|
|
||||||
|
/** Print background graphics and colors. */
|
||||||
|
public ?bool $printBackground = null;
|
||||||
|
|
||||||
|
/** Suggested filename for the PDF download. */
|
||||||
|
public ?string $filename = null;
|
||||||
|
|
||||||
|
/** HTML template for page header. Requires displayHeaderFooter: true. */
|
||||||
|
public ?string $headerTemplate = null;
|
||||||
|
|
||||||
|
/** HTML template for page footer. */
|
||||||
|
public ?string $footerTemplate = null;
|
||||||
|
|
||||||
|
/** Show header and footer templates. */
|
||||||
|
public ?bool $displayHeaderFooter = null;
|
||||||
|
|
||||||
|
/** Scale of webpage rendering (0.1 to 2.0). */
|
||||||
|
public ?float $scale = null;
|
||||||
|
|
||||||
|
/** Paper ranges to print, e.g. "1-3,5". */
|
||||||
|
public ?string $pageRanges = null;
|
||||||
|
|
||||||
|
/** Give CSS @page size priority over format. */
|
||||||
|
public ?bool $preferCSSPageSize = null;
|
||||||
|
|
||||||
|
/** Paper width with units (e.g. "8.5in"). Overrides format. */
|
||||||
|
public ?string $width = null;
|
||||||
|
|
||||||
|
/** Paper height with units (e.g. "11in"). Overrides format. */
|
||||||
|
public ?string $height = null;
|
||||||
|
|
||||||
|
public function toArray(): array
|
||||||
|
{
|
||||||
|
$data = [];
|
||||||
|
foreach ([
|
||||||
|
'format', 'landscape', 'margin', 'printBackground', 'filename',
|
||||||
|
'headerTemplate', 'footerTemplate', 'displayHeaderFooter',
|
||||||
|
'scale', 'pageRanges', 'preferCSSPageSize', 'width', 'height',
|
||||||
|
] as $key) {
|
||||||
|
if ($this->$key !== null) {
|
||||||
|
$data[$key] = $this->$key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue