Skip to content
Closed
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: 4 additions & 4 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ We're sorry to hear you have a problem. Can you help us solve it by providing th
attributes:
label: PHP Version
description: What version of PHP are you running? Please be as specific as possible
placeholder: "8.4.0"
value: "8.4.0"
placeholder: "8.5.0"
value: "8.5.0"
validations:
required: true
- type: input
id: laravel-version
attributes:
label: Laravel Version
description: What version of Laravel are you running? Please be as specific as possible
placeholder: "12.0.0"
value: "12.0.0"
placeholder: "13.0.0"
value: "13.0.0"
validations:
required: true
- type: dropdown
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/composer-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@2.37.0
with:
php-version: '8.4'
php-version: '8.5'
coverage: none

- name: Resolve dependencies and audit
Expand Down
13 changes: 11 additions & 2 deletions .github/workflows/fix-php-code-style-issues.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,17 @@ jobs:
- name: Checkout code
uses: actions/checkout@v6.0.2

- name: Fix PHP code style issues
uses: aglipanci/laravel-pint-action@2.6
- name: Setup PHP
uses: shivammathur/setup-php@2.37.0
with:
php-version: '8.5'
coverage: none

- name: Install composer dependencies
uses: ramsey/composer-install@4.0.0

- name: Run Laravel Pint
run: vendor/bin/pint

- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v7.1.0
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/phpstan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@2.37.0
with:
php-version: '8.4'
php-version: '8.5'
coverage: none

- name: Install composer dependencies
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ jobs:
max-parallel: 1
matrix:
os: [ ubuntu-latest ]
php: [ 8.2, 8.3, 8.4 ]
laravel: [ 12.* ]
php: [ 8.3, 8.4, 8.5 ]
laravel: [ 13.* ]
stability: [ prefer-lowest, prefer-stable ]

name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }}

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6.0.2

- name: Setup PHP
uses: shivammathur/setup-php@v2
uses: shivammathur/setup-php@2.37.0
with:
php-version: ${{ matrix.php }}
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo
Expand All @@ -45,7 +45,7 @@ jobs:
run: cp phpunit.xml.dist phpunit.xml

- name: Execute tests
run: vendor/bin/pest
run: vendor/bin/pest --no-coverage
env:
CLOUDINARY_CLOUD_NAME: ${{ secrets.CLOUDINARY_CLOUD_NAME }}
CLOUDINARY_API_KEY: ${{ secrets.CLOUDINARY_API_KEY }}
Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

All notable changes to `laravel-cloudinary` will be documented in this file.

## 13.0.0 - 2026-04-03

- Laravel 13 support
- PHP 8.3, 8.4, and 8.5 support (PHP 8.2 dropped)
- Development tooling: Orchestra Testbench 11, Pest 4, Larastan 3.9
- Packagist `dev-main` branch alias `13.x-dev` for Composer until `v13.0.0` is tagged
- **Flysystem 3:** `listContents()` now returns `FileAttributes` / `DirectoryAttributes` so `Storage::files()`, `Storage::directories()`, and related APIs work (fixes [#64](https://github.com/codebar-ag/laravel-flysystem-cloudinary/issues/64), [#80](https://github.com/codebar-ag/laravel-flysystem-cloudinary/issues/80))
- **Flysystem 3:** `read()` / `readStream()` throw `UnableToReadFile` on failure; `readStream()` returns a `resource`; `copy()` throws `UnableToCopyFile`; `delete()` throws `UnableToDeleteFile` when destroy fails; `createDirectory()` / `deleteDirectory()` throw the corresponding Flysystem exceptions
- Apply configured folder prefix to `move()`, `createDirectory()`, `deleteDirectory()`, and fix `directoryExists()` for root-level paths
- Fix string uploads: rewind temp stream after `fwrite()` before Cloudinary `upload()`
- `createDir()` catches `ApiError` as well as `RateLimited`
- Composer scripts: `analyse` (PHPStan), `test` / `test-coverage` via Pest with `--exclude-group=integration`; `format` uses Pint
- Integration tests: `integration` group, skip when placeholder Cloudinary env is used

## 2.0.0 - 2022-11-20

laravel-flysystem v3 upgrade:
Expand Down
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ additional parameters to your url 😉

| Package | PHP | Laravel | Flysystem |
|-----------|-------------|-----------|-------------|
| v12.0 | ^8.2 - ^8.4 | 12.x | 3.25.1 |
| v13.0 | 8.3.*–8.5.* | 13.x | 3.x |
| v12.0 | ^8.2 - ^8.4 | 12.x | 3.x |
| v11.0 | ^8.2 - ^8.3 | 11.x | 3.0 |
| v4.0 | ^8.2 - ^8.3 | 11.x | 3.0 |
| v3.0 | 8.2 | 10.x | 3.0 |
Expand Down Expand Up @@ -59,13 +60,23 @@ configuration:
Add the following environment variables to your `.env` file:

```shell
FILESYSTEM_DRIVER=cloudinary
FILESYSTEM_DISK=cloudinary

CLOUDINARY_CLOUD_NAME=my-cloud-name
CLOUDINARY_API_KEY=my-api-key
CLOUDINARY_API_SECRET=my-api-secret
```

Older Laravel apps may still use `FILESYSTEM_DRIVER`; Laravel 9+ prefers `FILESYSTEM_DISK`.

### Cloudinary folder modes

This adapter lists assets with the Admin API using **public ID `prefix`** and manages folders with **`subFolders` / `create_folder` / `delete_folder`**, which matches **legacy fixed folder mode** and typical public-ID paths. If your Cloudinary product environment uses **dynamic folder mode** only, some behaviours may differ; see [Folder modes](https://cloudinary.com/documentation/folder_modes) and the [Admin API](https://cloudinary.com/documentation/admin_api#folders).

### Continuous integration and integration tests

The test suite includes optional **integration** tests that call the live Cloudinary API. They run only when `CLOUDINARY_CLOUD_NAME`, `CLOUDINARY_API_KEY`, and `CLOUDINARY_API_SECRET` are set to real values (for example via GitHub Actions secrets). The default `composer test` command excludes the `integration` group; run `vendor/bin/pest` without `--exclude-group` to include them locally.

## 🏗 File extension problem

Let's look at the following example:
Expand Down
29 changes: 17 additions & 12 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codebar-ag/laravel-flysystem-cloudinary",
"description": "Cloudinary Flysystem v1 integration with Laravel",
"description": "Cloudinary Flysystem 3 integration with Laravel",
"keywords": [
"laravel",
"codebar-ag",
Expand All @@ -19,18 +19,18 @@
}
],
"require": {
"php": "8.2.*|8.3.*|8.4.*",
"php": "8.3.*|8.4.*|8.5.*",
"guzzlehttp/guzzle": "^7.8",
"illuminate/contracts": "^12.0",
"illuminate/contracts": "^13.0",
"cloudinary/cloudinary_php": "^2.13",
"nesbot/carbon": "^3.8",
"spatie/laravel-package-tools": "^1.19"
},
"require-dev": {
"laravel/pint": "^1.21",
"larastan/larastan": "^v3.1",
"orchestra/testbench": "^10.0",
"pestphp/pest": "^3.7",
"larastan/larastan": "^3.9",
"orchestra/testbench": "^11.0",
"pestphp/pest": "^4.0",
"phpstan/extension-installer": "^1.4",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
Expand All @@ -47,25 +47,30 @@
}
},
"scripts": {
"psalm": "vendor/bin/psalm",
"test": "./vendor/bin/testbench package:test --parallel --no-coverage --exclude-group=Integration",
"test-coverage": "vendor/bin/phpunit --coverage-html coverage --exclude-group=Integration",
"format": "vendor/bin/php-cs-fixer fix --allow-risky=yes"
"analyse": "vendor/bin/phpstan analyse",
"test": "vendor/bin/pest --no-coverage --exclude-group=integration",
"test-coverage": "vendor/bin/pest --coverage --exclude-group=integration",
"format": "vendor/bin/pint"
},
"config": {
"sort-packages": true,
"allow-plugins": {
"composer/package-versions-deprecated": false,
"pestphp/pest-plugin": true,
"phpstan/extension-installer": true
"phpstan/extension-installer": true,
"dealerdirect/phpcodesniffer-composer-installer": true
}
},
"extra": {
"branch-alias": {
"dev-main": "13.x-dev"
},
"laravel": {
"providers": [
"CodebarAg\\FlysystemCloudinary\\FlysystemCloudinaryServiceProvider"
]
}
},
"minimum-stability": "stable",
"minimum-stability": "dev",
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting the package minimum-stability to dev affects downstream consumers by allowing dev-only dependencies to be selected more readily, which can make installs less predictable. If the goal is only to support installing dev-main via the 13.x-dev branch alias, consider keeping minimum-stability at stable and documenting dev-main@dev usage instead.

Suggested change
"minimum-stability": "dev",

Copilot uses AI. Check for mistakes.
"prefer-stable": true
}
5 changes: 5 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ parameters:
checkOctaneCompatibility: true
checkModelProperties: true
noEnvCallsOutsideOfConfig: false
ignoreErrors:
-
identifier: argument.type
message: '#Parameter \#1 \$file of method Cloudinary\\Api\\Upload\\UploadApi::upload\(\) expects string#'
path: src/FlysystemCloudinaryAdapter.php
Comment on lines +13 to +17
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new ignoreErrors rule suppresses a type error for UploadApi::upload() expecting a string, which may hide a real bug and weaken static analysis across future changes. Prefer to adjust FlysystemCloudinaryAdapter::upload() so it passes a string path (or otherwise matches the SDK signature), and then remove this ignore rule.

Suggested change
ignoreErrors:
-
identifier: argument.type
message: '#Parameter \#1 \$file of method Cloudinary\\Api\\Upload\\UploadApi::upload\(\) expects string#'
path: src/FlysystemCloudinaryAdapter.php

Copilot uses AI. Check for mistakes.
2 changes: 1 addition & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
</logging>
<php>
<env name="APP_KEY" value="base64:F+mHMDBbavrsp/I3WYA5lDSwDJJI/0wQG4eM3csq/lo="/>
<env name="FILESYSTEM_DRIVER" value="cloudinary"/>
<env name="FILESYSTEM_DISK" value="cloudinary"/>
<env name="CLOUDINARY_CLOUD_NAME" value="cloudinary_cloud_name"/>
<env name="CLOUDINARY_API_KEY" value="cloudinary_api_key"/>
<env name="CLOUDINARY_API_SECRET" value="cloudinary_api_secret"/>
Expand Down
Loading