Download the PHP package pinoox/pinion without Composer

On this page you can find all versions of the php package pinoox/pinion. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package pinion

Pinion — Resumable Upload Protocol for PHP

Pinion (pinoox/pinion) lets users upload large files in small parts — even when PHP upload_max_filesize / post_max_size are low.

Protocol id: pinion · protocol version: 2 · PHP 8.2+

Layer Registry Package Release
Server (PHP) Packagist pinoox/pinion 1.1.0
Browser (JS) npm @pinooxhq/pinion-client 1.2.0

Protocol version (2) is the wire format (protocol_version in API responses). Release columns are separate semver for the PHP and npm packages.


Quick start

1 — Install

2 — Server: three HTTP steps

3 — Browser: one function

That is the whole idea: init → upload parts → complete. The client does the loop for you.


Table of contents


What is Pinion

The problem

On shared hosting or default PHP configs you often hit limits like:

A 500 MB video cannot be sent in one multipart/form-data request. Pinion splits the file into parts (default 5 MB), uploads them one by one, and assembles the final file on disk.

What Pinion is — and is not

Pinion is Pinion is not
A resumable chunked upload protocol Object storage (S3, MinIO)
A PHP library + JS client A CDN or media pipeline
A stable HTTP contract (pinion v2) A single /upload one-shot endpoint

When to use it

Scenario Why Pinion
Shared hosting (20 MB cap) Send 5 MB parts instead of one huge POST
Slow or mobile networks Resume after disconnect via fingerprint
Video / archive uploads Hundreds of MB or GB without raising php.ini limits
Admin panels & CMS Progress bar with parallel parts
API file intake Same contract across PHP stacks
Integrity-sensitive files SHA-256 per part (chunk_hash) + optional whole-file hash

How it works

Key concepts:

Concept Role
upload_id Server-side session UUID
fingerprint Client key name:size:lastModified:type — resume same file
chunk_size Bytes per part (negotiated at init)
missing_indexes Which parts still need uploading
chunk_hash SHA-256 of each part — verified if verify_chunks is on
destination Logical folder on server (uploads/videos)

Install

PHP — Packagist

Current release: 1.1.0 (pinoox/pinion)

Pinoox monorepo (local path):

JavaScript — npm

Current release: 1.2.0 (@pinooxhq/pinion-client)

Without npm (vendor copy)


Level 1 — Simple

Browser: upload one file

The fastest API — no setup object, no Axios:

unwrapPreset: 'pinoox' unwraps responses shaped like { data: { … } } (Pinoox / Laravel envelope). Use 'flat' if your API returns the payload directly.

Server: wire HTTP routes

Pinion needs five endpoints under one prefix. You choose the prefix; the client appends /init, /upload, etc.

Example prefix: /api/v1/upload

Method Route Handler
POST /api/v1/upload/init $handler->init($input)
POST /api/v1/upload/upload $handler->upload($input, $chunkFile)
POST /api/v1/upload/complete $handler->complete($input)
GET /api/v1/upload/status/{id} $handler->status($id)
POST /api/v1/upload/abort/{id} $handler->abort($id)

Minimal PHP router (no framework):

Return JSON from HttpHandler as-is, or map success / data / error to your framework response helper.

Routing & baseURL

baseURL in the JS client is the prefix only — not a single upload URL.

Your routes baseURL in client
/api/v1/upload/init, /upload, … '/api/v1/upload'
/api/pinion/init, … '/api/pinion'
/app/pinion/init, … (Pinoox manager) '/app/pinion'

The client calls:

If you only have one endpoint POST /api/v1/upload for a regular single-file upload, that is not Pinion — use FormData + fetch instead.


Level 2 — Practical patterns

Reusable uploader

Create one client, upload many files:

Progress, retry, parallel

With Axios (optional) you also get raw per-chunk upload events:

Small files vs large files

Use auto to skip Pinion for files below a threshold (default 8 MB):

Auth headers & CORS

Pass headers once on the client — they apply to every step (init, upload, complete):

On the server, ensure CORS allows POST + GET on all five routes if the frontend is on another origin.

Cancel an upload

Batch upload


Level 3 — Framework integration

Plain PHP

HTTP handler — recommended for web apps:

Fluent builder — for scripts and jobs:

Pinoox (HMVC)

Inside a Pinoox project use Pinoox\Portal\Pinion — config, temp storage, Flysystem/S3, and pinx_file integration are wired in pincore.

Piece Path Role
Portal Pinoox\Portal\Pinion App-facing API
Bridge pincore/Component/Pinion/ ProtocolManager, StorageCompletion, HttpHandler
Config pincore/config/pinion.config.php Chunk TTL, PINION_MODE, storage defaults
Trait PinionUploadActions Drop-in controller actions per app
CLI php pinoox pinion:list Ops on temp sessions

Storage modes (pinion.config.php → defaults.mode):

Mode Behaviour
auto Use Flysystem (Portal\File) when app filesystem.disk is not local (e.g. S3)
storage Always publish through managed file storage + optional FileModel row
local Assemble to project path via path() (legacy / manual folders)

Chunks always stage under storage/pinion. On complete, managed mode streams the assembled file to the app disk (local or S3) via UploadBuilder.

App controller (HMVC) — use the trait:

Local-only upload (no Flysystem — e.g. manager .pinx packages):

Browser client — npm @pinooxhq/pinion-client:

On complete with managed storage, the API returns file_id, url, and thumb (when applicable).

Routes (per app under apps/{package}/routes/):

→ client baseURL: '/app/pinion'

Template: pincore/config/pinion.routes.template.php

Config: pincore/config/pinion.config.php · temp: storage/pinion (pinion_uploads)

CLI:

Laravel

Laravel 10+ — auto-discovery via PinionServiceProvider.

1. Publish config

2. Routes (routes/api.php)

3. Controller

4. Facade (server-side jobs)


Level 4 — Advanced

Programmatic API (no HTTP)

Use Manager directly when chunks arrive from CLI, queue workers, or non-HTTP sources:

Low-level browser control (manual steps):

Resume & fingerprint

The client builds a fingerprint from file metadata:

On init, if the same fingerprint already has a pending session, the server returns it with resumed: true and missing_indexes — only missing parts are uploaded.

The JS client caches upload_id in localStorage (key: pinion_sessions) until complete succeeds.

Force resume explicitly:

Check stored session:

Checksums & integrity

Field When Purpose
chunk_hash Each POST /upload SHA-256 of that part — verified when verify_chunks: true
file_hash POST /init or /complete Optional whole-file hash — verified when verify_file_hash: true

Client sends chunk_hash automatically. To send whole-file hash on complete:

Configuration reference

Pass to Pinion::configure() or copy config/pinion.php.

Key Default Description
protocol pinion Protocol identifier (read-only in responses)
protocol_version 2 Protocol version
chunk_size 5242880 (5 MB) Default part size
min_chunk_size 1048576 (1 MB) Lower clamp
max_chunk_size 10485760 (10 MB) Upper clamp
ttl 86400 Session lifetime (seconds)
max_file_size 2147483648 (2 GB) Max declared file size
storage_path /tmp/pinion Temp workspace for in-progress uploads
storage_strategy parts parts or sparse
verify_chunks true Require matching chunk_hash
verify_file_hash false Require file_hash on complete

Laravel .env:

Per-request defaults via HttpHandler:

Storage strategies

Strategy On disk Best for
parts {id}/parts/0.part, 1.part, … Parallel client uploads (default)
sparse Single {id}/blob.part with offset writes Fewer files, sequential writes

Temp files live under storage_path. On complete, the assembled file moves to the resolved destination. Expired pending sessions are cleaned via cleanExpired().

Custom destinations

By default NativePathResolver maps to('uploads/videos') relative to a base path. For multi-root apps implement PathResolverInterface:

Maintenance & CLI

Pinoox CLI:


HTTP protocol (full reference)

Endpoints

Step Method Path Body
Init / resume POST {prefix}/init JSON
Upload part POST {prefix}/upload multipart/form-data
Complete POST {prefix}/complete JSON
Status GET {prefix}/status/{upload_id} —
Abort POST {prefix}/abort/{upload_id} JSON (optional)

Init request

Init response

Same fingerprint on a pending session → resumed: true, missing_indexes only lists gaps.

Upload part request

multipart/form-data fields:

Field Required Notes
upload_id yes Session UUID
index yes Zero-based part index
chunk yes Binary file field
chunk_hash recommended SHA-256 hex of chunk

Do not set Content-Type: multipart/form-data manually — let the client / browser set the boundary.

Complete request

Error envelope

HttpHandler returns:

Common codes: PINION_INIT_FAILED, PINION_INVALID, PINION_CHUNK_HASH_MISMATCH, PINION_SESSION_EXPIRED, PINION_FILE_TOO_LARGE.


Browser client (full reference)

Published as @pinooxhq/pinion-client 1.2.0. Detailed npm guide: client/README.md

Usage levels

Level API When
1 — Fastest uploadFile(file, options) Single button
2 — Fluent pinion({ baseURL }).for(file).upload() Reusable instance
3 — Full createPinionFetch(options) Batch, hooks, cancel
4 — Manual client.api.init() / uploadPart() / complete() Custom flow
5 — Axios pinion(axios, options) Per-chunk onUploadProgress
6 — Custom createPinionClient({ transport }) Own HTTP layer

Transport

Mode How client.transport.kind
fetch (default) pinion({ baseURL }) 'fetch'
Axios pinion(axios, { baseURL }) 'axios'

Unwrap presets

Preset Unwraps to
pinoox response.data.data
laravel same envelope
flat response.data
raw full response object

Set unwrapPreset: 'pinoox' when your PHP API wraps data in { data: … }.

Key exports

Export Role
uploadFile(file, options) One-shot upload
pinion(options) Fluent factory
createPinionFetch(options) Explicit fetch client
createPinionAxios(axios, options) { axios, client }
client.upload(file, opts) Full flow with parallel + retry
client.uploadMany(files, opts) Batch
client.api Low-level HTTP steps
buildFingerprint(file) Resume key
shouldUsePinion(file, threshold?) Skip Pinion for small files
sha256Hex(blob) Part checksum
PinionError Typed error with .code

PHP API surface

Class / method Role
Pinion::configure($config, $pathResolver?) Boot once
Pinion::manager() Manager singleton
Pinion::begin() Fluent Builder → init()
Pinion::http($defaults) HttpHandler for HTTP apps
Manager::init(...) Create or resume session
Manager::receive(...) Store one part
Manager::complete(...) Assemble final file
Manager::status(...) Progress + missing_indexes
Manager::abort(...) Cancel session
Manager::list($status) List sessions
Manager::cleanExpired() Purge expired pending
HttpHandler HTTP → { success, data?, error? }
Builder filename(), size(), to(), extensions(), fingerprint(), chunkSize(), init()
Session missingIndexes(), progress()
Result success, session, path, error, resumed
PathResolverInterface Map logical destination → absolute path

Pinoox (pincore): Pinoox\Portal\Pinion, Pinoox\Component\Pinion\HttpHandler, CLI commands.

Laravel: PinionServiceProvider, Pinion facade.


Troubleshooting

Symptom Likely cause Fix
PINION_INIT_FAILED in browser Wrong unwrapPreset Try pinoox, flat, or custom unwrap
404 on /upload Wrong baseURL baseURL = prefix only, not full file URL
Multipart rejected Manual Content-Type Let client set boundary on FormData
Upload stuck at N% Missing parts client.api.status(uploadId) → missing_indexes
chunk_hash mismatch Corrupt part or wrong hash Client computes SHA-256 per slice — don't transform binary
Session expired ttl exceeded Re-init; same fingerprint may start fresh
Small file uses Pinion unnecessarily No auto threshold uploadFile(file, { auto: true })
CORS error Preflight blocked Allow POST/GET on all five routes + credentials if needed
PINION_NO_FETCH (Node) No global fetch Node 18+ or pass options.fetch

Package structure


License

MIT — Pinoox


All versions of pinion with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
symfony/http-foundation Version ^6.4|^7.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package pinoox/pinion contains the following files

Loading the files please wait ...