Skip to content

Feature laravel13#90

Closed
StanBarrows wants to merge 7 commits into
mainfrom
feature-laravel13
Closed

Feature laravel13#90
StanBarrows wants to merge 7 commits into
mainfrom
feature-laravel13

Conversation

@StanBarrows
Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI review requested due to automatic review settings April 3, 2026 14:21
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR upgrades the package for Laravel 13 / PHP 8.3+ and refactors the Cloudinary Flysystem adapter to better align with Flysystem v3 behavior (exceptions + attribute objects), while reorganizing and expanding the test suite.

Changes:

  • Upgrade dependencies/tooling and CI to Laravel 13, PHP 8.3–8.5, Pest 4, Testbench 11, Larastan 3.9.
  • Refactor FlysystemCloudinaryAdapter by extracting responsibilities into focused classes (path normalization, disk options, URL building, list assembly, resource operations, metadata).
  • Update tests/docs to reflect Flysystem 3 semantics (iterable attributes from listContents, proper Flysystem exceptions, integration-test gating).

Reviewed changes

Copilot reviewed 42 out of 42 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/FlysystemCloudinaryServiceProvider.php Resolve disk options from disk config and pass into adapter during Storage::extend.
src/FlysystemCloudinaryAdapter.php Major refactor: extracted helpers, Flysystem v3 exception behavior, listContents() now returns attribute objects, added “last*” accessors.
src/Concerns/InteractsWithCloudinaryMetadata.php Shared metadata retrieval logic for adapter/test doubles.
src/CloudinaryUrlBuilder.php Centralizes delivery URL and explicit-URL selection (secure vs insecure).
src/CloudinaryStringUploadSource.php Temporary-file helper for uploading string bodies to Cloudinary SDK.
src/CloudinaryResponseMapper.php Normalizes Cloudinary responses and maps to FileAttributes.
src/CloudinaryResponseLogger.php Dispatches the response-log event.
src/CloudinaryResourceOperations.php Encapsulates explicit/destroy across resource types with logging.
src/CloudinaryPathNormalizer.php Handles folder prefixing and logical path mapping.
src/CloudinaryListResponseAssembler.php Builds shallow directory listings as FileAttributes/DirectoryAttributes.
src/CloudinaryDiskOptions.php Merges published config + disk config + per-operation Flysystem config for upload options and URL preference.
src/CloudinaryAdminFolderLocator.php Folder existence checks via Admin API pagination.
tests/Pest.php Adds shared integration helper loading and sets up adapter for Feature/Adapter tests; groups Integration tests.
tests/cloudinary_integration.php Skips live integration tests unless real Cloudinary env credentials are present.
tests/Integration/CloudinaryTest.php Updates integration expectations for Flysystem v3 semantics (exceptions, stream return types, etc.).
tests/Feature/FlysystemCloudinaryServiceProviderTest.php Ensures storage driver registration returns the Cloudinary adapter.
tests/Feature/Adapter/UploadWriteTest.php Splits legacy adapter tests: write/update + string upload behavior.
tests/Feature/Adapter/RenameCopyTest.php Covers rename/copy behavior, including folder-prefix behavior and exception cases.
tests/Feature/Adapter/ReadListHasTest.php Covers has/readStream/listContents behaviors under Flysystem v3 expectations.
tests/Feature/Adapter/DeleteDirectoryTest.php Covers delete/deleteDir/createDir and folder-prefix behavior.
tests/Feature/Adapter/UrlTest.php Covers URL generation paths.
tests/Feature/AdapterTest.php Removed monolithic feature test and replaced with focused Feature/Adapter test files.
tests/Unit/InteractsWithCloudinaryMetadataTest.php Unit tests for metadata trait mapping + error wrapping.
tests/Unit/FlysystemCloudinaryResponseLogTest.php Unit test for event payload.
tests/Unit/CloudinaryUrlBuilderTest.php Unit tests for URL builder behavior (NotFound, secure-url preference, logging).
tests/Unit/CloudinaryStringUploadSourceTest.php Unit tests for temp-file creation for string uploads.
tests/Unit/CloudinaryResponseMapperTest.php Unit tests for normalization + attribute mapping + extra metadata extraction.
tests/Unit/CloudinaryResponseLoggerTest.php Unit tests for event dispatch.
tests/Unit/CloudinaryResourceOperationsTest.php Unit tests for resource-type iteration behavior + logging.
tests/Unit/CloudinaryPathNormalizerTest.php Unit tests for prefixing/logical behavior.
tests/Unit/CloudinaryListResponseAssemblerTest.php Unit tests for list assembly into attribute objects.
tests/Unit/CloudinaryDiskOptionsTest.php Unit tests for option merge precedence.
tests/Unit/CloudinaryAdminFolderLocatorTest.php Unit tests for folder pagination and edge cases.
README.md Updates version matrix, config env var naming, and documents folder mode + integration test behavior.
phpunit.xml.dist Switches default filesystem env key to FILESYSTEM_DISK and keeps Cloudinary placeholders.
composer.json Laravel 13 + PHP 8.3+ constraints, tooling updates, scripts updated to Pest/PHPStan/Pint, adds branch-alias and changes stability.
CHANGELOG.md Documents v13.0.0 changes and behavioral notes.
.github/workflows/run-tests.yml Updates matrix to Laravel 13 / PHP 8.3–8.5 and runs Pest.
.github/workflows/phpstan.yml Updates PHP version used for static analysis.
.github/workflows/fix-php-code-style-issues.yml Switches formatting workflow to run Pint directly after installing deps.
.github/workflows/composer-audit.yml Updates PHP version used for audit job.
.github/ISSUE_TEMPLATE/bug_report.yml Updates PHP/Laravel placeholders to 8.5 / 13.0.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +88 to +92
$configurationProperty = new ReflectionProperty(Cloudinary::class, 'configuration');
if ($configurationProperty->isInitialized($cloudinary)) {
Configuration::instance($cloudinary->configuration);
}
}
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.

ReflectionProperty(Cloudinary::class, 'configuration') will throw a ReflectionException if the Cloudinary SDK changes internal property names (or removes the property). Since this is executed in the adapter constructor, it would hard-fail adapter instantiation. Consider guarding this with a try/catch around the reflection lookup (and/or checking property_exists), and only calling Configuration::instance(...) when the property both exists and is initialized.

Copilot uses AI. Check for mistakes.
Comment thread composer.json
}
},
"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 "minimum-stability": "dev" for the package increases the chance that CI/dev installs resolve to dev releases of dependencies (especially under prefer-lowest), which can make the test matrix flaky and harder to reproduce. Unless this is required for a specific dependency, consider keeping minimum-stability at stable and relying on explicit version constraints / @dev flags only where needed.

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

Copilot uses AI. Check for mistakes.
Comment on lines 44 to +48
- name: Execute tests
run: cp phpunit.xml.dist phpunit.xml

- name: Execute tests
run: vendor/bin/pest
run: vendor/bin/pest --no-coverage
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.

The workflow has two consecutive steps with the same name "Execute tests" (one copies phpunit.xml, the next runs Pest). Renaming the first to something like "Prepare phpunit.xml" makes CI logs clearer and avoids confusion when debugging failures.

Copilot uses AI. Check for mistakes.
*
* @var array<string, mixed>|false
*/
public array|false $meta;
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.

public array|false $meta; is a typed property without a default value and it’s not initialized in the constructor. Accessing $adapter->meta (or calling lastUploadMetadata()) before the first write will trigger a fatal "Typed property must not be accessed before initialization" error. Initialize it (e.g. default to false) in the property declaration and/or in the constructor.

Suggested change
public array|false $meta;
public array|false $meta = false;

Copilot uses AI. Check for mistakes.
Comment on lines +16 to +22
$folders = [];
$response = null;
do {
$response = (array) $cloudinary->adminApi()->subFolders($needle, [
'max_results' => 500,
'next_cursor' => $response['next_cursor'] ?? null,
]);
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.

$response starts as null, but the first loop iteration reads $response['next_cursor'] ?? null, which triggers a warning for array offset access on null in PHP 8+. Initializing $response to an empty array (or using a separate $nextCursor variable) avoids noisy warnings and prevents failures in environments that convert warnings to exceptions.

Copilot uses AI. Check for mistakes.
@StanBarrows StanBarrows closed this Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants