Skip to content

Commit c752ffa

Browse files
docs: add agent-readable documentation and repository metadata
Bring the repository up to the Cloudinary agent-readable documentation standard, following the structure shipped in cloudinary_npm (PRs #742 and #744). Documentation, shipped inside the Composer package so it is always version-matched to the installed code: - docs/ — 13 task pages with an index carrying the agent-rules banner. Every snippet was executed against a live cloud before being committed. - examples/ — 12 runnable files, one per task page, all verified green. Repository files: - README.md restructured: quick start, common tasks, when to use this SDK, compatibility, and a read path for coding agents. - AGENTS.md (six sections) plus CLAUDE.md; SECURITY.md with private vulnerability reporting; context7.json. Packaging: - .gitattributes decides what ships. docs/ and examples/ reach users at vendor/cloudinary/cloudinary_php/; tests/, tools/, samples/, apidocs/, and the lint/test configs no longer do. - The Sami API-doc tooling moves from docs/ to apidocs/ so that docs/ can hold the Markdown task docs, which is the path agents look for. tools/update_version.sh is updated to match. Corrections found by executing the documented calls rather than reading the source: - The API accessors are methods. The previous README documented $cloudinary->uploadApi->upload(...), which is a fatal error; it is $cloudinary->uploadApi()->upload(...). - ApiUtils is Cloudinary\Api\ApiUtils, although the file sits in src/Api/Utils/. - There is no uploadLarge(); upload() chunks automatically above chunk_size. - A partial configuration array replaces rather than merges, so passing only 'logging' discards credentials from CLOUDINARY_URL.
1 parent 4b989f4 commit c752ffa

45 files changed

Lines changed: 2805 additions & 99 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitattributes

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Files excluded from the Composer distribution archive.
2+
#
3+
# Composer ships the whole repository minus these entries, so `docs/` and `examples/`
4+
# reach users at vendor/cloudinary/cloudinary_php/ where coding agents can read them.
5+
# Development, test, and API-doc build tooling is excluded to keep vendor/ lean.
6+
7+
/.github/ export-ignore
8+
/.code-generation/ export-ignore
9+
/apidocs/ export-ignore
10+
/tests/ export-ignore
11+
/tools/ export-ignore
12+
/samples/ export-ignore
13+
/.gitattributes export-ignore
14+
/.gitignore export-ignore
15+
/context7.json export-ignore
16+
/.htaccess export-ignore
17+
/phpcs.xml export-ignore
18+
/phpstan.neon export-ignore
19+
/phpunit.xml export-ignore
20+
/CONTRIBUTING.md export-ignore
21+
/DEVELOPER_GUIDELINE.md export-ignore
22+
/AGENTS.md export-ignore
23+
/CLAUDE.md export-ignore

.gitignore

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ tests/coverage
44
output/
55
.idea
66
composer.phar
7-
docs/sami.phar
8-
docs/cache/
9-
docs/build/
7+
apidocs/sami.phar
8+
apidocs/cache/
9+
apidocs/build/
1010
tools/dev/sanity/node_modules
1111
tools/dev/sanity/package-lock.json
1212
tools/dev/sanity/results.json

AGENTS.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Contributor guide for coding agents
2+
3+
This file is for agents contributing to this repository. If you are *using* the installed
4+
`cloudinary/cloudinary_php` package in another project, read the bundled docs in
5+
`vendor/cloudinary/cloudinary_php/docs/` instead.
6+
7+
## Commands
8+
9+
```bash
10+
composer install # install dependencies
11+
vendor/bin/simple-phpunit --testsuite Unit # unit tests (mocked, no network)
12+
vendor/bin/simple-phpunit # full suite — needs a live cloud
13+
vendor/bin/phpcs # PSR-2 lint over src/ and tests/
14+
vendor/bin/phpcbf # auto-fix what phpcs can
15+
php examples/upload-image.php # run a documentation example
16+
```
17+
18+
Tests need a `CLOUDINARY_URL` in the environment. `bash tools/get_test_cloud.sh` prints a
19+
throwaway one, which is how CI does it:
20+
21+
```bash
22+
export CLOUDINARY_URL=$(bash tools/get_test_cloud.sh)
23+
```
24+
25+
`phpstan.neon` exists but PHPStan is not in `require-dev`; install it separately if you
26+
want to run it. `phpcs` currently reports pre-existing violations in `src/` and `tests/`
27+
do not mass-fix them in an unrelated pull request.
28+
29+
## Testing
30+
31+
- `tests/Unit/` is mocked and must never perform network calls.
32+
- `tests/Integration/` requires a real or temporary cloud. Do not run it by default, and
33+
do not add tests there that consume paid add-ons without a skip guard.
34+
- Nondeterministic AI output (captions, tags, moderation verdicts) must be asserted by
35+
request shape, state transition, and response schema — never by exact output values.
36+
- Some operations are unavailable on throwaway sub-account clouds — folder renaming
37+
returns `AuthorizationRequired`. Do not build tests or examples that depend on them.
38+
- `examples/` are executable documentation. If you change one, run it against a live cloud
39+
before committing; they are expected to exit 0 on success and 1 with a readable message
40+
when credentials are missing.
41+
42+
## Project structure
43+
44+
- `src/Cloudinary.php` — entry point. `uploadApi()`, `adminApi()`, and `searchApi()` are
45+
**methods**, and `image()`/`video()`/`imageTag()`/`videoTag()` build URLs and tags.
46+
- `src/Api/``Admin/`, `Upload/`, `Search/`, `Provisioning/`, plus `Exception/`.
47+
- `src/Configuration/` — configuration objects; input keys are `snake_case`, properties
48+
are `camelCase`.
49+
- `src/Asset/`, `src/Tag/` — URL builders and HTML tag builders.
50+
- Transformations live in the separate `cloudinary/transformation-builder-sdk` package
51+
under the `Cloudinary\Transformation` namespace, not in this repo.
52+
- `docs/` — version-matched Markdown task docs shipped in the Composer package.
53+
- `examples/` — runnable task examples, one per docs page, shipped in the package.
54+
- `apidocs/` — Sami API-doc generation tooling. Not shipped. Sami is abandoned and fails
55+
on PHP 8; the checked-in `apidocs/build/` output is stale.
56+
- `samples/` — legacy sample pages; not part of the tested example set.
57+
- `tools/` — release and test-cloud shell scripts.
58+
59+
Namespaces do not always mirror directories: `src/Api/Utils/ApiUtils.php` declares
60+
`namespace Cloudinary\Api`. Autoloading is a classmap over `src`, so check the
61+
`namespace` line rather than inferring from the path.
62+
63+
## Code style
64+
65+
- PSR-2, enforced by `phpcs`. Four-space indent, one class per file.
66+
- Examples in `examples/` trip PSR-1's "side effects" warning by design — they declare a
67+
`main()` and call it. Zero errors is the bar there, not zero warnings.
68+
- Public API methods take an options array and return `Cloudinary\Api\ApiResponse`, which
69+
extends `ArrayObject`:
70+
71+
```php
72+
public function upload(mixed $file, array $options = []): ApiResponse
73+
{
74+
return $this->uploadAsync($file, $options)->wait();
75+
}
76+
```
77+
78+
- Async variants (`...Async`) return a Guzzle `PromiseInterface`; the sync method wraps it
79+
with `->wait()`. Add both when adding an API method.
80+
81+
## Git workflow
82+
83+
- Branch from `master`; keep changes focused; one topic per pull request.
84+
- Run `vendor/bin/simple-phpunit --testsuite Unit` before opening a PR.
85+
- Do not rewrite published changelog entries; add new entries at the top.
86+
- The version string lives in `composer.json`, `src/Cloudinary.php` (`const VERSION`), and
87+
`apidocs/sami_config.php`. `tools/update_version.sh` rewrites all three by exact string
88+
match — do not reformat those lines.
89+
- Never commit credentials, `.env` files, or generated output.
90+
91+
## Boundaries
92+
93+
**Always**
94+
- Keep `docs/` and `examples/` consistent with the code they document.
95+
- Execute a documentation snippet against a live cloud before committing it; reading the
96+
source and writing what it appears to do has produced wrong docs repeatedly.
97+
- Keep API secrets out of examples, docs, tests, and fixtures.
98+
99+
**Ask first**
100+
- Changing supported PHP versions, dependencies, or `.gitattributes` `export-ignore`
101+
entries — the latter decides what ships to users' `vendor/`.
102+
- Renaming or removing any public method or exported symbol.
103+
- Changing release, CI, or publishing configuration.
104+
105+
**Never**
106+
- Commit credentials or real account identifiers.
107+
- Perform live network calls in unit tests.
108+
- Document a Cloudinary platform capability as an SDK method unless this package
109+
implements it (see `docs/platform-capabilities.md`).

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@AGENTS.md

README.md

Lines changed: 108 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,145 @@
1-
[![Tests](https://github.com/cloudinary/cloudinary_php/actions/workflows/test.yaml/badge.svg)](https://github.com/cloudinary/cloudinary_php/actions/workflows/test.yaml)
2-
[![license](https://img.shields.io/github/license/cloudinary/cloudinary_php.svg?maxAge=2592000)](https://github.com/cloudinary/cloudinary_php/blob/master/LICENSE)
3-
[![Packagist](https://img.shields.io/packagist/v/cloudinary/cloudinary_php.svg?maxAge=2592000)](https://packagist.org/packages/cloudinary/cloudinary_php)
4-
[![Packagist](https://img.shields.io/packagist/dt/cloudinary/cloudinary_php.svg?maxAge=2592000)](https://packagist.org/packages/cloudinary/cloudinary_php/stats)
5-
6-
Cloudinary PHP SDK
7-
==================
8-
9-
## About
1+
# Cloudinary PHP SDK
102

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

14-
#### Note
15-
16-
This Readme provides basic installation and usage information.
17-
For the complete documentation, see the [PHP SDK Guide](https://cloudinary.com/documentation/php_integration).
5+
[![Tests](https://github.com/cloudinary/cloudinary_php/actions/workflows/test.yaml/badge.svg)](https://github.com/cloudinary/cloudinary_php/actions/workflows/test.yaml)
6+
[![Packagist](https://img.shields.io/packagist/v/cloudinary/cloudinary_php.svg)](https://packagist.org/packages/cloudinary/cloudinary_php)
7+
[![License](https://img.shields.io/packagist/l/cloudinary/cloudinary_php.svg)](LICENSE)
188

19-
## Table of Contents
9+
## Install
2010

21-
- [Key Features](#key-features)
22-
- [Version Support](#Version-Support)
23-
- [Installation](#installation)
24-
- [Usage](#usage)
25-
- [Setup](#Setup)
26-
- [Transform and Optimize Assets](#Transform-and-Optimize-Assets)
11+
```bash
12+
composer require cloudinary/cloudinary_php
13+
```
2714

28-
## Key Features
15+
## Quick start
2916

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

37-
## Version Support
19+
```bash
20+
export CLOUDINARY_URL=cloudinary://<api_key>:<api_secret>@<cloud_name>
21+
```
3822

39-
| SDK Version | PHP 5.4 | PHP 5.5 | PHP 5.6 | PHP 7.x | PHP 8.0 - 8.3 | PHP 8.4 |
40-
|-------------|---------|---------|---------|---------|---------------|---------|
41-
| 3.x |||||||
42-
| 2.x |||||| ✘ * |
43-
| 1.x |||||||
23+
Upload an image and get an optimized delivery URL:
4424

45-
\* Deprecation warnings
25+
```php
26+
<?php
4627

47-
## Installation
28+
require 'vendor/autoload.php';
4829

49-
```bash
50-
composer require "cloudinary/cloudinary_php"
30+
use Cloudinary\Cloudinary;
31+
use Cloudinary\Transformation\Delivery;
32+
use Cloudinary\Transformation\Format;
33+
use Cloudinary\Transformation\Gravity;
34+
use Cloudinary\Transformation\Quality;
35+
use Cloudinary\Transformation\Resize;
36+
37+
try {
38+
$cloudinary = new Cloudinary();
39+
40+
// Upload a remote image (a local file path works the same way).
41+
$result = $cloudinary->uploadApi()->upload(
42+
'https://res.cloudinary.com/demo/image/upload/sample.jpg',
43+
['public_id' => 'quickstart-sample']
44+
);
45+
46+
echo 'Uploaded: ', $result['public_id'], PHP_EOL;
47+
48+
// Build a 400x400 auto-cropped URL with automatic format and quality.
49+
$url = $cloudinary->image($result['public_id'])
50+
->resize(Resize::fill(400, 400)->gravity(Gravity::auto()))
51+
->delivery(Delivery::format(Format::auto()))
52+
->delivery(Delivery::quality(Quality::auto()));
53+
54+
echo 'Optimized URL: ', $url, PHP_EOL;
55+
} catch (Throwable $e) {
56+
fwrite(STDERR, 'Quick start failed: ' . $e->getMessage() . PHP_EOL);
57+
fwrite(STDERR, 'Check that CLOUDINARY_URL is set (Console > Settings > API Keys).' . PHP_EOL);
58+
exit(1);
59+
}
5160
```
5261

53-
# Usage
54-
55-
### Migration
62+
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).
5663

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

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

62-
### Setup
68+
- [Get Cloudinary credentials](docs/get-credentials.md)
69+
- [Import and call the SDK](docs/import-and-call.md)
70+
- [Configure Cloudinary](docs/configure-cloudinary.md)
71+
- [Upload an image](docs/upload-image.md)
72+
- [Upload a large video](docs/upload-large-video.md)
73+
- [Sign a browser upload](docs/sign-browser-upload.md)
74+
- [Transform and deliver an image](docs/transform-and-deliver-image.md)
75+
- [Transform and deliver a video](docs/transform-and-deliver-video.md)
76+
- [Search and manage assets](docs/search-and-manage-assets.md)
77+
- [Moderate an upload](docs/moderate-upload.md)
78+
- [Use structured metadata](docs/use-structured-metadata.md)
79+
- [Troubleshoot errors](docs/troubleshoot-errors.md)
6380

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

67-
$cloudinary = new Cloudinary();
68-
```
83+
## When to use this SDK
6984

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

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

74-
```php
75-
$cloudinary->image('sample.jpg')->resize(Resize::fill()->width(100)->height(150))->format(Format::auto());
76-
```
91+
- Laravel-native integration with facades and a storage driver: [`cloudinary-labs/cloudinary-laravel`](https://github.com/cloudinary-labs/cloudinary-laravel).
92+
- WordPress, Magento, and similar platforms: [platform integrations](https://cloudinary.com/documentation/integrations) ([md](https://cloudinary.com/documentation/integrations.md)).
93+
- Browser or frontend framework rendering: [frontend SDKs](https://cloudinary.com/documentation/frontend_sdks) ([md](https://cloudinary.com/documentation/frontend_sdks.md)).
94+
- Complete in-browser upload UI: [Upload Widget](https://cloudinary.com/documentation/upload_widget) ([md](https://cloudinary.com/documentation/upload_widget.md)).
95+
- 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.
96+
- Multi-step media workflow automation: [MediaFlows](https://cloudinary.com/documentation/mediaflows_user_guide) ([md](https://cloudinary.com/documentation/mediaflows_user_guide.md)).
97+
- 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)).
7798

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

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

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

87-
### Security options
106+
| SDK version | PHP |
107+
|-------------|-----|
108+
| 3.x | 8.0 and later |
109+
| 2.x | 5.6 – 8.3 (no longer maintained) |
110+
| 1.x | 5.4 – 7.x (no longer maintained) |
88111

89-
- [See full documentation](https://cloudinary.com/documentation/solution_overview#security).
112+
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)).
90113

91-
## Contributions
114+
## Documentation
92115

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

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

98-
If you run into an issue or have a question, you can either:
125+
## For AI coding agents
99126

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

103-
## About Cloudinary
132+
## Support
104133

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

109-
## Additional Resources
137+
## Security
110138

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

128-
## Licence
143+
## License
129144

130-
Released under the MIT license.
145+
Released under the MIT license — see [LICENSE](LICENSE). Copyright (c) Cloudinary Ltd.

0 commit comments

Comments
 (0)