Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Files excluded from the Composer distribution archive.
#
# Composer ships the whole repository minus these entries, so `docs/` and `examples/`
# reach users at vendor/cloudinary/cloudinary_php/ where coding agents can read them.
# Development, test, and API-doc build tooling is excluded to keep vendor/ lean.

/.github/ export-ignore
/.code-generation/ export-ignore
/apidocs/ export-ignore
/tests/ export-ignore
/tools/ export-ignore
/samples/ export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/context7.json export-ignore
/.htaccess export-ignore
/phpcs.xml export-ignore
/phpstan.neon export-ignore
/phpunit.xml export-ignore
/CONTRIBUTING.md export-ignore
/DEVELOPER_GUIDELINE.md export-ignore
/AGENTS.md export-ignore
/CLAUDE.md export-ignore
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ tests/coverage
output/
.idea
composer.phar
docs/sami.phar
docs/cache/
docs/build/
apidocs/sami.phar
apidocs/cache/
apidocs/build/
tools/dev/sanity/node_modules
tools/dev/sanity/package-lock.json
tools/dev/sanity/results.json
Expand Down
109 changes: 109 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Contributor guide for coding agents

This file is for agents contributing to this repository. If you are *using* the installed
`cloudinary/cloudinary_php` package in another project, read the bundled docs in
`vendor/cloudinary/cloudinary_php/docs/` instead.

## Commands

```bash
composer install # install dependencies
vendor/bin/simple-phpunit --testsuite Unit # unit tests (mocked, no network)
vendor/bin/simple-phpunit # full suite — needs a live cloud
vendor/bin/phpcs # PSR-2 lint over src/ and tests/
vendor/bin/phpcbf # auto-fix what phpcs can
php examples/upload-image.php # run a documentation example
```

Tests need a `CLOUDINARY_URL` in the environment. `bash tools/get_test_cloud.sh` prints a
throwaway one, which is how CI does it:

```bash
export CLOUDINARY_URL=$(bash tools/get_test_cloud.sh)
```

`phpstan.neon` exists but PHPStan is not in `require-dev`; install it separately if you
want to run it. `phpcs` currently reports pre-existing violations in `src/` and `tests/` —
do not mass-fix them in an unrelated pull request.

## Testing

- `tests/Unit/` is mocked and must never perform network calls.
- `tests/Integration/` requires a real or temporary cloud. Do not run it by default, and
do not add tests there that consume paid add-ons without a skip guard.
- Nondeterministic AI output (captions, tags, moderation verdicts) must be asserted by
request shape, state transition, and response schema — never by exact output values.
- Some operations are unavailable on throwaway sub-account clouds — folder renaming
returns `AuthorizationRequired`. Do not build tests or examples that depend on them.
- `examples/` are executable documentation. If you change one, run it against a live cloud
before committing; they are expected to exit 0 on success and 1 with a readable message
when credentials are missing.

## Project structure

- `src/Cloudinary.php` — entry point. `uploadApi()`, `adminApi()`, and `searchApi()` are
**methods**, and `image()`/`video()`/`imageTag()`/`videoTag()` build URLs and tags.
- `src/Api/` — `Admin/`, `Upload/`, `Search/`, `Provisioning/`, plus `Exception/`.
- `src/Configuration/` — configuration objects; input keys are `snake_case`, properties
are `camelCase`.
- `src/Asset/`, `src/Tag/` — URL builders and HTML tag builders.
- Transformations live in the separate `cloudinary/transformation-builder-sdk` package
under the `Cloudinary\Transformation` namespace, not in this repo.
- `docs/` — version-matched Markdown task docs shipped in the Composer package.
- `examples/` — runnable task examples, one per docs page, shipped in the package.
- `apidocs/` — Sami API-doc generation tooling. Not shipped. Sami is abandoned and fails
on PHP 8; the checked-in `apidocs/build/` output is stale.
- `samples/` — legacy sample pages; not part of the tested example set.
- `tools/` — release and test-cloud shell scripts.

Namespaces do not always mirror directories: `src/Api/Utils/ApiUtils.php` declares
`namespace Cloudinary\Api`. Autoloading is a classmap over `src`, so check the
`namespace` line rather than inferring from the path.

## Code style

- PSR-2, enforced by `phpcs`. Four-space indent, one class per file.
- Examples in `examples/` trip PSR-1's "side effects" warning by design — they declare a
`main()` and call it. Zero errors is the bar there, not zero warnings.
- Public API methods take an options array and return `Cloudinary\Api\ApiResponse`, which
extends `ArrayObject`:

```php
public function upload(mixed $file, array $options = []): ApiResponse
{
return $this->uploadAsync($file, $options)->wait();
}
```

- Async variants (`...Async`) return a Guzzle `PromiseInterface`; the sync method wraps it
with `->wait()`. Add both when adding an API method.

## Git workflow

- Branch from `master`; keep changes focused; one topic per pull request.
- Run `vendor/bin/simple-phpunit --testsuite Unit` before opening a PR.
- Do not rewrite published changelog entries; add new entries at the top.
- The version string lives in `composer.json`, `src/Cloudinary.php` (`const VERSION`), and
`apidocs/sami_config.php`. `tools/update_version.sh` rewrites all three by exact string
match — do not reformat those lines.
- Never commit credentials, `.env` files, or generated output.

## Boundaries

**Always**
- Keep `docs/` and `examples/` consistent with the code they document.
- Execute a documentation snippet against a live cloud before committing it; reading the
source and writing what it appears to do has produced wrong docs repeatedly.
- Keep API secrets out of examples, docs, tests, and fixtures.

**Ask first**
- Changing supported PHP versions, dependencies, or `.gitattributes` `export-ignore`
entries — the latter decides what ships to users' `vendor/`.
- Renaming or removing any public method or exported symbol.
- Changing release, CI, or publishing configuration.

**Never**
- Commit credentials or real account identifiers.
- Perform live network calls in unit tests.
- Document a Cloudinary platform capability as an SDK method unless this package
implements it (see `docs/platform-capabilities.md`).
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
202 changes: 109 additions & 93 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,130 +1,146 @@
[![Tests](https://github.com/cloudinary/cloudinary_php/actions/workflows/test.yaml/badge.svg)](https://github.com/cloudinary/cloudinary_php/actions/workflows/test.yaml)
[![license](https://img.shields.io/github/license/cloudinary/cloudinary_php.svg?maxAge=2592000)](https://github.com/cloudinary/cloudinary_php/blob/master/LICENSE)
[![Packagist](https://img.shields.io/packagist/v/cloudinary/cloudinary_php.svg?maxAge=2592000)](https://packagist.org/packages/cloudinary/cloudinary_php)
[![Packagist](https://img.shields.io/packagist/dt/cloudinary/cloudinary_php.svg?maxAge=2592000)](https://packagist.org/packages/cloudinary/cloudinary_php/stats)

Cloudinary PHP SDK
==================

## About
# Cloudinary PHP SDK

The Cloudinary PHP SDK allows you to quickly and easily integrate your application with Cloudinary.
Effortlessly optimize, transform, upload and manage your cloud's assets.
Upload, transform, optimize, and manage images and videos with Cloudinary from PHP — the `cloudinary/cloudinary_php` package on Packagist.

#### Note

This Readme provides basic installation and usage information.
For the complete documentation, see the [PHP SDK Guide](https://cloudinary.com/documentation/php_integration).
[![Tests](https://github.com/cloudinary/cloudinary_php/actions/workflows/test.yaml/badge.svg)](https://github.com/cloudinary/cloudinary_php/actions/workflows/test.yaml)
[![Packagist](https://img.shields.io/packagist/v/cloudinary/cloudinary_php.svg)](https://packagist.org/packages/cloudinary/cloudinary_php)
[![Downloads](https://img.shields.io/packagist/dm/cloudinary/cloudinary_php.svg)](https://packagist.org/packages/cloudinary/cloudinary_php/stats)
[![License](https://img.shields.io/packagist/l/cloudinary/cloudinary_php.svg)](LICENSE)

## Table of Contents
## Install

- [Key Features](#key-features)
- [Version Support](#Version-Support)
- [Installation](#installation)
- [Usage](#usage)
- [Setup](#Setup)
- [Transform and Optimize Assets](#Transform-and-Optimize-Assets)
```bash
composer require cloudinary/cloudinary_php
```

## Key Features
## Quick start

- [Transform](https://cloudinary.com/documentation/php_video_manipulation#video_transformation_examples) and
[optimize](https://cloudinary.com/documentation/php_image_manipulation#image_optimizations) assets.
- Generate [image](https://cloudinary.com/documentation/php_image_manipulation#deliver_and_transform_images) and
[video](https://cloudinary.com/documentation/php_video_manipulation#php_video_transformation_code_examples) tags.
- [Asset Management](https://cloudinary.com/documentation/php_asset_administration).
- [Secure URLs](https://cloudinary.com/documentation/video_manipulation_and_delivery#generating_secure_https_urls_using_sdks).
Set your API environment variable (Console > Settings > API Keys):

## Version Support
```bash
export CLOUDINARY_URL=cloudinary://<api_key>:<api_secret>@<cloud_name>
```

| SDK Version | PHP 5.4 | PHP 5.5 | PHP 5.6 | PHP 7.x | PHP 8.0 - 8.3 | PHP 8.4 |
|-------------|---------|---------|---------|---------|---------------|---------|
| 3.x | ✘ | ✘ | ✘ | ✘ | ✔ | ✔ |
| 2.x | ✘ | ✘ | ✔ | ✔ | ✔ | ✘ * |
| 1.x | ✔ | ✔ | ✔ | ✔ | ✘ | ✘ |
Upload an image and get an optimized delivery URL:

\* Deprecation warnings
```php
<?php

## Installation
require 'vendor/autoload.php';

```bash
composer require "cloudinary/cloudinary_php"
use Cloudinary\Cloudinary;
use Cloudinary\Transformation\Delivery;
use Cloudinary\Transformation\Format;
use Cloudinary\Transformation\Gravity;
use Cloudinary\Transformation\Quality;
use Cloudinary\Transformation\Resize;

try {
$cloudinary = new Cloudinary();

// Upload a remote image (a local file path works the same way).
$result = $cloudinary->uploadApi()->upload(
'https://res.cloudinary.com/demo/image/upload/sample.jpg',
['public_id' => 'quickstart-sample']
);

echo 'Uploaded: ', $result['public_id'], PHP_EOL;

// Build a 400x400 auto-cropped URL with automatic format and quality.
$url = $cloudinary->image($result['public_id'])
->resize(Resize::fill(400, 400)->gravity(Gravity::auto()))
->delivery(Delivery::format(Format::auto()))
->delivery(Delivery::quality(Quality::auto()));

echo 'Optimized URL: ', $url, PHP_EOL;
} catch (Throwable $e) {
fwrite(STDERR, 'Quick start failed: ' . $e->getMessage() . PHP_EOL);
fwrite(STDERR, 'Check that CLOUDINARY_URL is set (Console > Settings > API Keys).' . PHP_EOL);
exit(1);
}
```

# Usage

### Migration
Save as `quickstart.php` and run `php quickstart.php`. [Create a free account](https://cloudinary.com/users/register_free) if you don't have one — or run `npx @cloudinary/cloud` to [provision one without signing up](docs/get-credentials.md).

See the [Cloudinary PHP SDK Migration guide](https://cloudinary.com/documentation/php2_migration) for more information
on migrating to this version of the PHP SDK.
`uploadApi()`, `adminApi()`, and `searchApi()` are methods — call them with parentheses.

The previous (1.x) version of the SDK is located [here](https://github.com/cloudinary/cloudinary_php/tree/support/1.x).
## Common tasks

### Setup
- [Get Cloudinary credentials](docs/get-credentials.md)
- [Import and call the SDK](docs/import-and-call.md)
- [Configure Cloudinary](docs/configure-cloudinary.md)
- [Upload an image](docs/upload-image.md)
- [Upload a large video](docs/upload-large-video.md)
- [Sign a browser upload](docs/sign-browser-upload.md)
- [Transform and deliver an image](docs/transform-and-deliver-image.md)
- [Transform and deliver a video](docs/transform-and-deliver-video.md)
- [Search and manage assets](docs/search-and-manage-assets.md)
- [Moderate an upload](docs/moderate-upload.md)
- [Use structured metadata](docs/use-structured-metadata.md)
- [Troubleshoot errors](docs/troubleshoot-errors.md)

```php
use Cloudinary\Cloudinary;
Runnable versions live in [`examples/`](examples/) — each is a complete file you can run directly.

$cloudinary = new Cloudinary();
```
## When to use this SDK

### Transform and Optimize Assets
Use this package in **PHP server-side code**: uploads, signed operations, asset
administration, search, moderation, and delivery URL generation. It works with any
framework, and with none.

- [See full documentation](https://cloudinary.com/documentation/php_image_manipulation).
For other jobs, better-fitting tools exist:

```php
$cloudinary->image('sample.jpg')->resize(Resize::fill()->width(100)->height(150))->format(Format::auto());
```
- Laravel-native integration with facades and a storage driver: [`cloudinary-labs/cloudinary-laravel`](https://github.com/cloudinary-labs/cloudinary-laravel).
- WordPress, Magento, and similar platforms: [platform integrations](https://cloudinary.com/documentation/integrations) ([md](https://cloudinary.com/documentation/integrations.md)).
- Browser or frontend framework rendering: [frontend SDKs](https://cloudinary.com/documentation/frontend_sdks) ([md](https://cloudinary.com/documentation/frontend_sdks.md)).
- Complete in-browser upload UI: [Upload Widget](https://cloudinary.com/documentation/upload_widget) ([md](https://cloudinary.com/documentation/upload_widget.md)).
- Text-to-image generation and image-to-video: [platform APIs](https://cloudinary.com/documentation/image_generation_addon) ([md](https://cloudinary.com/documentation/image_generation_addon.md)), not wrapped by this package.
- Multi-step media workflow automation: [MediaFlows](https://cloudinary.com/documentation/mediaflows_user_guide) ([md](https://cloudinary.com/documentation/mediaflows_user_guide.md)).
- Interactive agent-driven asset operations: [Cloudinary MCP servers and Skills](https://cloudinary.com/documentation/cloudinary_llm_mcp) ([md](https://cloudinary.com/documentation/cloudinary_llm_mcp.md)).

### Upload
The full capability map — plus the Skills, MCP servers, and CLI worth setting up first —
is in [docs/platform-capabilities.md](docs/platform-capabilities.md).

- [See full documentation](https://cloudinary.com/documentation/php_image_and_video_upload).
- [Learn more about configuring your uploads with upload presets](https://cloudinary.com/documentation/upload_presets).
## Status and compatibility

```php
$cloudinary->uploadApi->upload('my_image.jpg');
```
Stable, actively maintained. See [CHANGELOG.md](CHANGELOG.md).

### Security options
| SDK version | PHP |
|-------------|-----|
| 3.x | 8.0 and later |
| 2.x | 5.6 – 8.3 (no longer maintained) |
| 1.x | 5.4 – 7.x (no longer maintained) |

- [See full documentation](https://cloudinary.com/documentation/solution_overview#security).
The 1.x series lives on the [`support/1.x`](https://github.com/cloudinary/cloudinary_php/tree/support/1.x) branch. Moving from it? See the [migration guide](https://cloudinary.com/documentation/php2_migration) ([md](https://cloudinary.com/documentation/php2_migration.md)).

## Contributions
## Documentation

- Ensure tests run locally
- Open a PR and ensure Travis tests pass
- [Bundled task docs](docs/README.md) — ship inside the package, version-matched.
- [PHP SDK guide](https://cloudinary.com/documentation/php_integration) — the full documentation ([md](https://cloudinary.com/documentation/php_integration.md)).
- [Transformation and API reference](https://cloudinary.com/documentation/cloudinary_references) ([md](https://cloudinary.com/documentation/cloudinary_references.md)).

## Get Help
Documentation links in this README point at the browsable HTML page, with an `(md)`
companion link that returns the same page as raw Markdown. Inside `docs/` and `examples/`
the links are Markdown-only, since those files are written to be read by coding agents.
Either form works for any page: add `.md` for Markdown, drop it for HTML.

If you run into an issue or have a question, you can either:
## For AI coding agents

- Issues related to the SDK: [Open a GitHub issue](https://github.com/cloudinary/cloudinary_php/issues).
- Issues related to your account: [Open a support ticket](https://cloudinary.com/contact)
- Contributing to this repo: read [AGENTS.md](AGENTS.md).
- Using the installed package: the docs in `vendor/cloudinary/cloudinary_php/docs/` match
your installed version and are the source of truth; start with
[platform-capabilities](docs/platform-capabilities.md) before assuming a feature exists.

## About Cloudinary
## Support

Cloudinary is a powerful media API for websites and mobile apps alike, Cloudinary enables developers to efficiently
manage, transform, optimize, and deliver images and videos through multiple CDNs. Ultimately, viewers enjoy responsive
and personalized visual-media experiences—irrespective of the viewing device.
- SDK bugs and feature requests: [GitHub issues](https://github.com/cloudinary/cloudinary_php/issues)
- Account and platform questions: [Cloudinary support](https://support.cloudinary.com)

## Additional Resources
## Security

- [Cloudinary Transformation and REST API References](https://cloudinary.com/documentation/cloudinary_references):
Comprehensive references, including syntax and examples for all SDKs.
- [MediaJams.dev](https://mediajams.dev/): Bite-size use-case tutorials written by and for Cloudinary Developers
- [DevJams](https://www.youtube.com/playlist?list=PL8dVGjLA2oMr09amgERARsZyrOz_sPvqw): Cloudinary developer podcasts on
YouTube.
- [Cloudinary Academy](https://training.cloudinary.com/): Free self-paced courses, instructor-led virtual courses, and
on-site courses.
- [Code Explorers and Feature Demos](https://cloudinary.com/documentation/code_explorers_demos_index): A one-stop shop
for all code explorers, Postman collections, and feature demos found in the docs.
- [Cloudinary Roadmap](https://cloudinary.com/roadmap): Your chance to follow, vote, or suggest what Cloudinary should
develop next.
- [Cloudinary Facebook Community](https://www.facebook.com/groups/CloudinaryCommunity): Learn from and offer help to
other Cloudinary developers.
- [Cloudinary Account Registration](https://cloudinary.com/users/register/free): Free Cloudinary account registration.
- [Cloudinary Website](https://cloudinary.com): Learn about Cloudinary's products, partners, customers, pricing, and
more.
See [SECURITY.md](SECURITY.md) for private vulnerability reporting. Keep your
`api_secret` in server-side code; for client uploads, use the server-signed pattern in
[Sign a browser upload](docs/sign-browser-upload.md).

## Licence
## License

Released under the MIT license.
Released under the MIT license — see [LICENSE](LICENSE). Copyright (c) Cloudinary Ltd.
Loading
Loading