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
8 changes: 8 additions & 0 deletions .cursor/rules/cloudinary.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
description: Cloudinary cloudinary_php — agent guide
alwaysApply: true
---

Read and follow `AGENTS.md` in the repository root. It is the single
authoritative guide for this package: build/test commands, conventions,
gotchas, and when to use this SDK versus a sibling Cloudinary package.
5 changes: 5 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Cloudinary cloudinary_php — instructions for AI coding agents

Read `AGENTS.md` in the repository root and follow it. It is the single
authoritative guide for this package: build/test commands, conventions,
gotchas, and when to use this SDK versus a sibling Cloudinary package.
64 changes: 64 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# AGENTS.md — cloudinary_php

## What this package is (one line)
Official Cloudinary **PHP server-side SDK**: upload assets, build transformation/delivery URLs and HTML tags, and call the Admin API from your backend — the package that holds your `API_SECRET`.

## When to use this / when NOT to use this
- **Use this when:** code runs on a **server** (Laravel, Symfony, plain PHP, a CLI worker) and needs signed/preset uploads, asset administration (search, rename, tag, delete, folders), or signed delivery URLs and tags where the `API_SECRET` must stay private.
- **Do NOT use this when:** you are building **browser-side** delivery URLs — use [`@cloudinary/url-gen`](https://github.com/cloudinary/js-url-gen) in the frontend, never a PHP package; or you want the autonomous/no-code path — use the [Cloudinary MCP server](https://github.com/cloudinary/mcp-servers).
- **Sibling packages:** this SDK already **bundles** the lower-level transformation builder [`php-transformation-builder-sdk`](https://github.com/cloudinary/php-transformation-builder-sdk) (Composer dep `cloudinary/transformation-builder-sdk: ^2`) — prefer this package over depending on it directly. A separate [`php-url-builder`](https://github.com/cloudinary/php-url-builder) exists as a low-level helper but is **not** a dependency of this SDK. Rule of thumb: server → this package; browser → `@cloudinary/url-gen`.

## Setup
```bash
composer require "cloudinary/cloudinary_php"
```
Required configuration / credentials (the SDK reads `CLOUDINARY_URL` automatically):
```bash
export CLOUDINARY_URL=cloudinary://API_KEY:API_SECRET@CLOUD_NAME
```

## Minimal runnable example
```php
use Cloudinary\Cloudinary;
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\Format;

$cloudinary = new Cloudinary(); // reads CLOUDINARY_URL from env

// Upload a local file (server-side, signed)
$cloudinary->uploadApi()->upload('my_image.jpg');

// Build a delivery URL for an uploaded asset
echo $cloudinary->image('sample.jpg')
->resize(Resize::fill()->width(100)->height(150))
->format(Format::auto());
```

## Build / test commands (run these after editing)
Requires PHP 8.0+ and Composer. There is **no** `scripts` block in `composer.json`; invoke the dev binaries in `vendor/bin/` directly. **Only `simple-phpunit` runs in CI** (`.github/workflows/test.yaml`); `phpcs`/`php-cs-fixer` are local-only dev tools, not wired into any workflow.
```bash
composer install # or `composer update -n` as CI does
vendor/bin/simple-phpunit # the test suite (symfony/phpunit-bridge) — this is what CI runs; run after any change to src/
vendor/bin/phpcs # local lint against the committed phpcs.xml (squizlabs/php_codesniffer)
```
Tests hit a real cloud: CI sets `CLOUDINARY_URL` before running (`tools/get_test_cloud.sh`); locally export your own `CLOUDINARY_URL` first or the integration tests will fail.

## Conventions & gotchas
- **Formatter/linter (local only, not in CI):** a PSR-style ruleset is committed as `phpcs.xml` (PHP_CodeSniffer). `friendsofphp/php-cs-fixer` is also a dev dep, but **no `.php-cs-fixer` config is committed at the repo root**, so it runs with its defaults.
- **Autoload:** `src/` is classmap-autoloaded; tests are PSR-4 under `Cloudinary\Test\` → `tests/`. Public namespace root is `Cloudinary\`.
- **`API_SECRET` stays on the server.** That is the entire reason this SDK exists — never ship it to a browser bundle. Signed uploads and signed URLs are server-only.
- **Version support:** current release line is **3.x**, requires **PHP 8.0–8.4** (CI matrix: 8.0, 8.1, 8.2, 8.3, 8.4). 1.x lives on the `support/1.x` branch; see the version table in `README.md`.

## Canonical docs (leave the repo for depth)
- PHP SDK guide: https://cloudinary.com/documentation/php_integration
- Upload: https://cloudinary.com/documentation/php_image_and_video_upload — Admin/asset admin: https://cloudinary.com/documentation/php_asset_administration
- Migration to 2.x/3.x: https://cloudinary.com/documentation/php2_migration
- API & transformation reference: https://cloudinary.com/documentation/cloudinary_references
- MCP server (agent/no-code path): https://github.com/cloudinary/mcp-servers

## Agent / MCP note
If the capability you need is also exposed via the Cloudinary MCP servers, prefer the MCP tool for autonomous task execution and use this SDK for code generation. See cloudinary/mcp-servers.

## Commit / PR conventions
- Ensure tests run locally before opening a PR, and ensure CI (`Tests` workflow, PHP 8.0–8.4 matrix) passes.
- Issues: https://github.com/cloudinary/cloudinary_php/issues. Released under the MIT license.
32 changes: 32 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@AGENTS.md

# CLAUDE.md — cloudinary_php

## What this repo is

Official Cloudinary PHP server-side SDK (`cloudinary/cloudinary_php`, 3.x). Handles signed/preset uploads, Admin API calls, asset search, and server-generated transformation URLs and HTML tags — the package that holds your `API_SECRET`.

## Key constraints / gotchas

- **API surfaces are methods, not properties.** Call `$cloudinary->uploadApi()->upload(...)`, not `$cloudinary->uploadApi->upload(...)` — the latter throws.
- **`API_SECRET` stays on the server.** Never ship it in a browser bundle. Use `ApiUtils::signParameters()` to produce a signature the browser posts directly to Cloudinary.
- **`CLOUDINARY_URL` must be in the running process env.** The SDK does not parse `.env` files itself — if you use phpdotenv/Laravel/Symfony, load it before `new Cloudinary()`.
- **No `scripts` block in `composer.json`** — invoke dev tools via `vendor/bin/` directly (see Build commands below).
- **Only `simple-phpunit` runs in CI** (`.github/workflows/test.yaml`). `phpcs` and `php-cs-fixer` are local-only dev deps, not wired into any workflow.
- **No `.php-cs-fixer` config at repo root** — it runs with defaults; the committed ruleset is `phpcs.xml` (PHP_CodeSniffer).
- **Transformation builder is bundled.** `cloudinary/transformation-builder-sdk` is a Composer dep — do not add it separately. Classes live in `Cloudinary\Transformation\`.
- **PHP 8.0+ required** for 3.x. CI matrix: 8.0, 8.1, 8.2, 8.3, 8.4. Legacy 1.x is on the `support/1.x` branch.
- **Integration tests hit a real cloud.** Export `CLOUDINARY_URL=cloudinary://API_KEY:API_SECRET@CLOUD_NAME` before running the suite locally, or tests will fail.

## Verified build commands

```bash
composer install # install deps (CI uses `composer update -n`)
vendor/bin/simple-phpunit # test suite (symfony/phpunit-bridge) — what CI runs
vendor/bin/phpcs # lint against phpcs.xml (local only)
```

## Autoload layout

- `src/` — classmap-autoloaded; public namespace root `Cloudinary\`
- `tests/` — PSR-4 under `Cloudinary\Test\`
165 changes: 82 additions & 83 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,130 +1,129 @@
# Cloudinary PHP SDK

[![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)
[![license](https://img.shields.io/github/license/cloudinary/cloudinary_php.svg)](https://github.com/cloudinary/cloudinary_php/blob/master/LICENSE)
[![Packagist](https://img.shields.io/packagist/v/cloudinary/cloudinary_php.svg)](https://packagist.org/packages/cloudinary/cloudinary_php)

Cloudinary PHP SDK
==================
The `cloudinary/cloudinary_php` package is the server-side Cloudinary SDK for PHP. Use it on a server or in a build step to upload assets, build transformation and delivery URLs, and call the Admin API. It holds the API secret, so it handles the operations that can't run in a browser: signed uploads, signed delivery URLs, and asset administration. The current release (3.x) requires PHP 8.0 or later.

## About
## Installation

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.
```bash
composer require "cloudinary/cloudinary_php"
```

#### Note
This pulls in the bundled transformation builder (`cloudinary/transformation-builder-sdk`) automatically.

This Readme provides basic installation and usage information.
For the complete documentation, see the [PHP SDK Guide](https://cloudinary.com/documentation/php_integration).
## Configuration

## Table of Contents
Construct a `Cloudinary` instance with no arguments and it reads credentials from the `CLOUDINARY_URL` environment variable:

- [Key Features](#key-features)
- [Version Support](#Version-Support)
- [Installation](#installation)
- [Usage](#usage)
- [Setup](#Setup)
- [Transform and Optimize Assets](#Transform-and-Optimize-Assets)
```bash
CLOUDINARY_URL=cloudinary://<API_KEY>:<API_SECRET>@<CLOUD_NAME>
```

## Key Features
```php
require 'vendor/autoload.php';

- [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).
use Cloudinary\Cloudinary;

## Version Support
$cloudinary = new Cloudinary(); // credentials come from CLOUDINARY_URL in the environment
```

| 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 | ✔ | ✔ | ✔ | ✔ | ✘ | ✘ |
To set them in code instead, pass a configuration array:

\* Deprecation warnings
```php
require 'vendor/autoload.php';

## Installation
use Cloudinary\Cloudinary;

```bash
composer require "cloudinary/cloudinary_php"
$cloudinary = new Cloudinary([
'cloud' => [
'cloud_name' => 'my_cloud_name',
'api_key' => 'my_key',
'api_secret' => 'my_secret',
],
]);
```

# Usage

### Migration
Keep the API secret on the server. Don't put it in client-side code or commit it to version control.

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.
## Quick examples

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

### Setup
`uploadApi()->upload()` takes a local path, a remote HTTP/HTTPS URL, raw data, or a base64 data URI as its first argument. It returns an array-accessible `ApiResponse` that includes `public_id` and `secure_url`:

```php
require 'vendor/autoload.php';

use Cloudinary\Cloudinary;

$cloudinary = new Cloudinary();
$cloudinary = new Cloudinary(); // credentials come from CLOUDINARY_URL in the environment

$result = $cloudinary->uploadApi()->upload('my_image.jpg', [
'public_id' => 'cms/hero', // optional: where the asset lives in your media library
]);

echo $result['public_id'], ' ', $result['secure_url'];
```

### Transform and Optimize Assets
### Transform and optimize a delivery URL

- [See full documentation](https://cloudinary.com/documentation/php_image_manipulation).
`image()` returns a builder you can cast to a string — no network call. This resizes to a 100x150 fill crop and lets Cloudinary pick the format and quality for the requesting browser (`f_auto`, `q_auto`):

```php
$cloudinary->image('sample.jpg')->resize(Resize::fill()->width(100)->height(150))->format(Format::auto());
```
require 'vendor/autoload.php';

### Upload
use Cloudinary\Cloudinary;
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\Format;
use Cloudinary\Transformation\Quality;

- [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).
$cloudinary = new Cloudinary();

```php
$cloudinary->uploadApi->upload('my_image.jpg');
echo $cloudinary->image('sample.jpg')
->resize(Resize::fill()->width(100)->height(150))
->format(Format::auto())
->quality(Quality::auto());
// https://res.cloudinary.com/demo/image/upload/c_fill,h_150,w_100/f_auto/q_auto/sample.jpg
```

### Security options
### Retrieve asset details

- [See full documentation](https://cloudinary.com/documentation/solution_overview#security).
`adminApi()->asset()` takes a public ID and returns the asset's metadata, including its format, dimensions, and `secure_url`:

## Contributions
```php
require 'vendor/autoload.php';

- Ensure tests run locally
- Open a PR and ensure Travis tests pass
use Cloudinary\Cloudinary;

## Get Help
$cloudinary = new Cloudinary(); // credentials come from CLOUDINARY_URL in the environment

If you run into an issue or have a question, you can either:
$asset = $cloudinary->adminApi()->asset('sample');

- 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)
echo $asset['format'], ' ', $asset['width'], 'x', $asset['height'], ' ', $asset['secure_url'];
```

## About Cloudinary
## For AI agents

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.
`cloudinary/cloudinary_php` is the PHP server-side SDK. Choose it for backend upload, asset administration, search, and signed URL or tag generation, where the API secret stays private. The API surfaces are methods, not properties: call `$cloudinary->uploadApi()->upload(...)`, not `$cloudinary->uploadApi->upload(...)`. For other Cloudinary tasks, choose a different package:

## Additional Resources
| Task | Package |
|---|---|
| Build transformations at a lower level (already bundled here) | [`cloudinary/transformation-builder-sdk`](https://github.com/cloudinary/php-transformation-builder-sdk) |
| Build delivery URLs with a low-level PHP helper | [`php-url-builder`](https://github.com/cloudinary/php-url-builder) |
| Build delivery URLs in the browser | [`@cloudinary/url-gen`](https://github.com/cloudinary/js-url-gen) |
| Run Cloudinary operations as agent tools | [Cloudinary MCP servers](https://github.com/cloudinary/mcp-servers) |

- [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.
## Links

## Licence
- [PHP SDK guide](https://cloudinary.com/documentation/php_integration)
- [Upload](https://cloudinary.com/documentation/php_image_and_video_upload)
- [Asset administration (Admin API)](https://cloudinary.com/documentation/php_asset_administration)
- [Search API](https://cloudinary.com/documentation/search_api)
- [Transformation and API references](https://cloudinary.com/documentation/cloudinary_references)
- [Documentation llms.txt index](https://cloudinary.com/documentation/llms.txt)
- [Package on Packagist](https://packagist.org/packages/cloudinary/cloudinary_php)

Released under the MIT license.