diff --git a/assets/admin-settings.js b/assets/admin-settings.js new file mode 100644 index 0000000..6061389 --- /dev/null +++ b/assets/admin-settings.js @@ -0,0 +1,20 @@ +// assets/admin-settings.js +(function ($) { + const toggleSections = () => { + const adapter = $('#flysystem-offload-adapter').val(); + $('.flysystem-offload-adapter-section').hide(); + $(`.flysystem-offload-adapter-section[data-adapter="${adapter}"]`).show(); + }; + + $(document).ready(function () { + const $heading = $('h2:contains("Amazon S3 / Compatible")'); + const $table = $heading.next('table'); + + if ($heading.length && $table.length) { + $heading.add($table).wrapAll('
'); + } + + toggleSections(); + $('#flysystem-offload-adapter').on('change', toggleSections); + }); +})(jQuery); diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..d45704c --- /dev/null +++ b/composer.json @@ -0,0 +1,23 @@ +{ + "name": "tu-nombre/flysystem-offload", + "description": "Universal storage offloading for WordPress vía Flysystem", + "type": "wordpress-plugin", + "require": { + "php": ">=7.4", + "league/flysystem": "^3.24", + "league/flysystem-aws-s3-v3": "^3.24", + "league/flysystem-sftp-v3": "^3.24", + "league/flysystem-azure-blob-storage": "^3.24", + "league/flysystem-google-cloud-storage": "^3.24", + "league/flysystem-webdav": "^3.24", + "aws/aws-sdk-php": "^3.330", + "google/cloud-storage": "^1.33", + "microsoft/azure-storage-blob": "^1.5", + "sabre/dav": "^4.5" + }, + "autoload": { + "psr-4": { + "FlysystemOffload\\": "src/" + } + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..6681439 --- /dev/null +++ b/composer.lock @@ -0,0 +1,3138 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "89f20bba8c2c3b8ae0b9ff469bef830c", + "packages": [ + { + "name": "aws/aws-crt-php", + "version": "v1.2.7", + "source": { + "type": "git", + "url": "https://github.com/awslabs/aws-crt-php.git", + "reference": "d71d9906c7bb63a28295447ba12e74723bd3730e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/d71d9906c7bb63a28295447ba12e74723bd3730e", + "reference": "d71d9906c7bb63a28295447ba12e74723bd3730e", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35||^5.6.3||^9.5", + "yoast/phpunit-polyfills": "^1.0" + }, + "suggest": { + "ext-awscrt": "Make sure you install awscrt native extension to use any of the functionality." + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "AWS SDK Common Runtime Team", + "email": "aws-sdk-common-runtime@amazon.com" + } + ], + "description": "AWS Common Runtime for PHP", + "homepage": "https://github.com/awslabs/aws-crt-php", + "keywords": [ + "amazon", + "aws", + "crt", + "sdk" + ], + "support": { + "issues": "https://github.com/awslabs/aws-crt-php/issues", + "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.7" + }, + "time": "2024-10-18T22:15:13+00:00" + }, + { + "name": "aws/aws-sdk-php", + "version": "3.359.3", + "source": { + "type": "git", + "url": "https://github.com/aws/aws-sdk-php.git", + "reference": "a32e4c9522f0b61c947fafa1713d3a24b397a757" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/a32e4c9522f0b61c947fafa1713d3a24b397a757", + "reference": "a32e4c9522f0b61c947fafa1713d3a24b397a757", + "shasum": "" + }, + "require": { + "aws/aws-crt-php": "^1.2.3", + "ext-json": "*", + "ext-pcre": "*", + "ext-simplexml": "*", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/promises": "^2.0", + "guzzlehttp/psr7": "^2.4.5", + "mtdowling/jmespath.php": "^2.8.0", + "php": ">=8.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "require-dev": { + "andrewsville/php-token-reflection": "^1.4", + "aws/aws-php-sns-message-validator": "~1.0", + "behat/behat": "~3.0", + "composer/composer": "^2.7.8", + "dms/phpunit-arraysubset-asserts": "^0.4.0", + "doctrine/cache": "~1.4", + "ext-dom": "*", + "ext-openssl": "*", + "ext-pcntl": "*", + "ext-sockets": "*", + "phpunit/phpunit": "^5.6.3 || ^8.5 || ^9.5", + "psr/cache": "^2.0 || ^3.0", + "psr/simple-cache": "^2.0 || ^3.0", + "sebastian/comparator": "^1.2.3 || ^4.0 || ^5.0", + "symfony/filesystem": "^v6.4.0 || ^v7.1.0", + "yoast/phpunit-polyfills": "^2.0" + }, + "suggest": { + "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", + "doctrine/cache": "To use the DoctrineCacheAdapter", + "ext-curl": "To send requests using cURL", + "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages", + "ext-sockets": "To use client-side monitoring" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Aws\\": "src/" + }, + "exclude-from-classmap": [ + "src/data/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Amazon Web Services", + "homepage": "http://aws.amazon.com" + } + ], + "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", + "homepage": "http://aws.amazon.com/sdkforphp", + "keywords": [ + "amazon", + "aws", + "cloud", + "dynamodb", + "ec2", + "glacier", + "s3", + "sdk" + ], + "support": { + "forum": "https://github.com/aws/aws-sdk-php/discussions", + "issues": "https://github.com/aws/aws-sdk-php/issues", + "source": "https://github.com/aws/aws-sdk-php/tree/3.359.3" + }, + "time": "2025-10-31T18:15:22+00:00" + }, + { + "name": "brick/math", + "version": "0.14.0", + "source": { + "type": "git", + "url": "https://github.com/brick/math.git", + "reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/math/zipball/113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2", + "reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2", + "shasum": "" + }, + "require": { + "php": "^8.2" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpstan/phpstan": "2.1.22", + "phpunit/phpunit": "^11.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "bignumber", + "brick", + "decimal", + "integer", + "math", + "mathematics", + "rational" + ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.14.0" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + } + ], + "time": "2025-08-29T12:40:03+00:00" + }, + { + "name": "firebase/php-jwt", + "version": "v6.11.1", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/d1e91ecf8c598d073d0995afa8cd5c75c6e19e66", + "reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^7.4", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psr/cache": "^2.0||^3.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0" + }, + "suggest": { + "ext-sodium": "Support EdDSA (Ed25519) signatures", + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "keywords": [ + "jwt", + "php" + ], + "support": { + "issues": "https://github.com/firebase/php-jwt/issues", + "source": "https://github.com/firebase/php-jwt/tree/v6.11.1" + }, + "time": "2025-04-09T20:32:01+00:00" + }, + { + "name": "google/auth", + "version": "v1.48.1", + "source": { + "type": "git", + "url": "https://github.com/googleapis/google-auth-library-php.git", + "reference": "023f41a2c80fb98a493dfb9dffcab643481a7ab0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/023f41a2c80fb98a493dfb9dffcab643481a7ab0", + "reference": "023f41a2c80fb98a493dfb9dffcab643481a7ab0", + "shasum": "" + }, + "require": { + "firebase/php-jwt": "^6.0", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/psr7": "^2.4.5", + "php": "^8.1", + "psr/cache": "^2.0||^3.0", + "psr/http-message": "^1.1||^2.0", + "psr/log": "^3.0" + }, + "require-dev": { + "guzzlehttp/promises": "^2.0", + "kelvinmo/simplejwt": "0.7.1", + "phpseclib/phpseclib": "^3.0.35", + "phpspec/prophecy-phpunit": "^2.1", + "phpunit/phpunit": "^9.6", + "sebastian/comparator": ">=1.2.3", + "squizlabs/php_codesniffer": "^4.0", + "symfony/process": "^6.0||^7.0", + "webmozart/assert": "^1.11" + }, + "suggest": { + "phpseclib/phpseclib": "May be used in place of OpenSSL for signing strings or for token management. Please require version ^2." + }, + "type": "library", + "autoload": { + "psr-4": { + "Google\\Auth\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Google Auth Library for PHP", + "homepage": "https://github.com/google/google-auth-library-php", + "keywords": [ + "Authentication", + "google", + "oauth2" + ], + "support": { + "docs": "https://cloud.google.com/php/docs/reference/auth/latest", + "issues": "https://github.com/googleapis/google-auth-library-php/issues", + "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.48.1" + }, + "time": "2025-09-30T04:22:33+00:00" + }, + { + "name": "google/cloud-core", + "version": "v1.68.2", + "source": { + "type": "git", + "url": "https://github.com/googleapis/google-cloud-php-core.git", + "reference": "f33d7c3e912d83ea731d08975e79de1c3b8c19d1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/googleapis/google-cloud-php-core/zipball/f33d7c3e912d83ea731d08975e79de1c3b8c19d1", + "reference": "f33d7c3e912d83ea731d08975e79de1c3b8c19d1", + "shasum": "" + }, + "require": { + "google/auth": "^1.34", + "google/gax": "^1.38.0", + "guzzlehttp/guzzle": "^6.5.8||^7.4.4", + "guzzlehttp/promises": "^1.4||^2.0", + "guzzlehttp/psr7": "^2.6", + "monolog/monolog": "^2.9||^3.0", + "php": "^8.1", + "psr/http-message": "^1.0||^2.0", + "rize/uri-template": "~0.3||~0.4" + }, + "require-dev": { + "erusev/parsedown": "^1.6", + "google/cloud-common-protos": "~0.5", + "opis/closure": "^3.7|^4.0", + "phpdocumentor/reflection": "^5.3.3||^6.0", + "phpdocumentor/reflection-docblock": "^5.3", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.0", + "squizlabs/php_codesniffer": "2.*" + }, + "suggest": { + "opis/closure": "May be used to serialize closures to process jobs in the batch daemon. Please require version ^3.", + "symfony/lock": "Required for the Spanner cached based session pool. Please require the following commit: 3.3.x-dev#1ba6ac9" + }, + "bin": [ + "bin/google-cloud-batch" + ], + "type": "library", + "extra": { + "component": { + "id": "cloud-core", + "path": "Core", + "entry": "src/ServiceBuilder.php", + "target": "googleapis/google-cloud-php-core.git" + } + }, + "autoload": { + "psr-4": { + "Google\\Cloud\\Core\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Google Cloud PHP shared dependency, providing functionality useful to all components.", + "support": { + "source": "https://github.com/googleapis/google-cloud-php-core/tree/v1.68.2" + }, + "time": "2025-10-25T01:16:28+00:00" + }, + { + "name": "google/cloud-storage", + "version": "v1.48.6", + "source": { + "type": "git", + "url": "https://github.com/googleapis/google-cloud-php-storage.git", + "reference": "5bf41093390ab08d3287a291e67f3768ca35e66d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/googleapis/google-cloud-php-storage/zipball/5bf41093390ab08d3287a291e67f3768ca35e66d", + "reference": "5bf41093390ab08d3287a291e67f3768ca35e66d", + "shasum": "" + }, + "require": { + "google/cloud-core": "^1.57", + "php": "^8.1", + "ramsey/uuid": "^4.2.3" + }, + "require-dev": { + "erusev/parsedown": "^1.6", + "google/cloud-pubsub": "^2.0", + "phpdocumentor/reflection": "^5.3.3||^6.0", + "phpdocumentor/reflection-docblock": "^5.3", + "phpseclib/phpseclib": "^2.0||^3.0", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.0", + "squizlabs/php_codesniffer": "2.*" + }, + "suggest": { + "google/cloud-pubsub": "May be used to register a topic to receive bucket notifications.", + "phpseclib/phpseclib": "May be used in place of OpenSSL for creating signed Cloud Storage URLs. Please require version ^2." + }, + "type": "library", + "extra": { + "component": { + "id": "cloud-storage", + "path": "Storage", + "entry": "src/StorageClient.php", + "target": "googleapis/google-cloud-php-storage.git" + } + }, + "autoload": { + "psr-4": { + "Google\\Cloud\\Storage\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Cloud Storage Client for PHP", + "support": { + "source": "https://github.com/googleapis/google-cloud-php-storage/tree/v1.48.6" + }, + "time": "2025-10-27T23:48:29+00:00" + }, + { + "name": "google/common-protos", + "version": "4.12.4", + "source": { + "type": "git", + "url": "https://github.com/googleapis/common-protos-php.git", + "reference": "0127156899af0df2681bd42024c60bd5360d64e3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/googleapis/common-protos-php/zipball/0127156899af0df2681bd42024c60bd5360d64e3", + "reference": "0127156899af0df2681bd42024c60bd5360d64e3", + "shasum": "" + }, + "require": { + "google/protobuf": "^4.31", + "php": "^8.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.6" + }, + "type": "library", + "extra": { + "component": { + "id": "common-protos", + "path": "CommonProtos", + "entry": "README.md", + "target": "googleapis/common-protos-php.git" + } + }, + "autoload": { + "psr-4": { + "Google\\Api\\": "src/Api", + "Google\\Iam\\": "src/Iam", + "Google\\Rpc\\": "src/Rpc", + "Google\\Type\\": "src/Type", + "Google\\Cloud\\": "src/Cloud", + "GPBMetadata\\Google\\Api\\": "metadata/Api", + "GPBMetadata\\Google\\Iam\\": "metadata/Iam", + "GPBMetadata\\Google\\Rpc\\": "metadata/Rpc", + "GPBMetadata\\Google\\Type\\": "metadata/Type", + "GPBMetadata\\Google\\Cloud\\": "metadata/Cloud", + "GPBMetadata\\Google\\Logging\\": "metadata/Logging" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Google API Common Protos for PHP", + "homepage": "https://github.com/googleapis/common-protos-php", + "keywords": [ + "google" + ], + "support": { + "source": "https://github.com/googleapis/common-protos-php/tree/v4.12.4" + }, + "time": "2025-09-20T01:29:44+00:00" + }, + { + "name": "google/gax", + "version": "v1.38.0", + "source": { + "type": "git", + "url": "https://github.com/googleapis/gax-php.git", + "reference": "0e1bce4a30722e85485bbb132b2fa811d66b397b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/googleapis/gax-php/zipball/0e1bce4a30722e85485bbb132b2fa811d66b397b", + "reference": "0e1bce4a30722e85485bbb132b2fa811d66b397b", + "shasum": "" + }, + "require": { + "google/auth": "^1.45", + "google/common-protos": "^4.4", + "google/grpc-gcp": "^0.4", + "google/longrunning": "~0.4", + "google/protobuf": "^4.31", + "grpc/grpc": "^1.13", + "guzzlehttp/promises": "^2.0", + "guzzlehttp/psr7": "^2.0", + "php": "^8.1", + "ramsey/uuid": "^4.0" + }, + "conflict": { + "ext-protobuf": "<4.31.0" + }, + "require-dev": { + "phpspec/prophecy-phpunit": "^2.1", + "phpstan/phpstan": "^2.0", + "phpunit/phpunit": "^9.6", + "squizlabs/php_codesniffer": "4.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "Google\\ApiCore\\": "src", + "GPBMetadata\\ApiCore\\": "metadata/ApiCore" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Google API Core for PHP", + "homepage": "https://github.com/googleapis/gax-php", + "keywords": [ + "google" + ], + "support": { + "issues": "https://github.com/googleapis/gax-php/issues", + "source": "https://github.com/googleapis/gax-php/tree/v1.38.0" + }, + "time": "2025-09-17T18:22:14+00:00" + }, + { + "name": "google/grpc-gcp", + "version": "v0.4.1", + "source": { + "type": "git", + "url": "https://github.com/GoogleCloudPlatform/grpc-gcp-php.git", + "reference": "e585b7721bbe806ef45b5c52ae43dfc2bff89968" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GoogleCloudPlatform/grpc-gcp-php/zipball/e585b7721bbe806ef45b5c52ae43dfc2bff89968", + "reference": "e585b7721bbe806ef45b5c52ae43dfc2bff89968", + "shasum": "" + }, + "require": { + "google/auth": "^1.3", + "google/protobuf": "^v3.25.3||^4.26.1", + "grpc/grpc": "^v1.13.0", + "php": "^8.0", + "psr/cache": "^1.0.1||^2.0.0||^3.0.0" + }, + "require-dev": { + "google/cloud-spanner": "^1.7", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Grpc\\Gcp\\": "src/" + }, + "classmap": [ + "src/generated/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "gRPC GCP library for channel management", + "support": { + "issues": "https://github.com/GoogleCloudPlatform/grpc-gcp-php/issues", + "source": "https://github.com/GoogleCloudPlatform/grpc-gcp-php/tree/v0.4.1" + }, + "time": "2025-02-19T21:53:22+00:00" + }, + { + "name": "google/longrunning", + "version": "0.6.0", + "source": { + "type": "git", + "url": "https://github.com/googleapis/php-longrunning.git", + "reference": "226d3b5166eaa13754cc5e452b37872478e23375" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/googleapis/php-longrunning/zipball/226d3b5166eaa13754cc5e452b37872478e23375", + "reference": "226d3b5166eaa13754cc5e452b37872478e23375", + "shasum": "" + }, + "require-dev": { + "google/gax": "^1.38.0", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "component": { + "id": "longrunning", + "path": "LongRunning", + "entry": null, + "target": "googleapis/php-longrunning" + } + }, + "autoload": { + "psr-4": { + "Google\\LongRunning\\": "src/LongRunning", + "Google\\ApiCore\\LongRunning\\": "src/ApiCore/LongRunning", + "GPBMetadata\\Google\\Longrunning\\": "metadata/Longrunning" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Google LongRunning Client for PHP", + "support": { + "source": "https://github.com/googleapis/php-longrunning/tree/v0.6.0" + }, + "time": "2025-10-07T18:41:09+00:00" + }, + { + "name": "google/protobuf", + "version": "v4.33.0", + "source": { + "type": "git", + "url": "https://github.com/protocolbuffers/protobuf-php.git", + "reference": "b50269e23204e5ae859a326ec3d90f09efe3047d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/b50269e23204e5ae859a326ec3d90f09efe3047d", + "reference": "b50269e23204e5ae859a326ec3d90f09efe3047d", + "shasum": "" + }, + "require": { + "php": ">=8.1.0" + }, + "require-dev": { + "phpunit/phpunit": ">=5.0.0 <8.5.27" + }, + "suggest": { + "ext-bcmath": "Need to support JSON deserialization" + }, + "type": "library", + "autoload": { + "psr-4": { + "Google\\Protobuf\\": "src/Google/Protobuf", + "GPBMetadata\\Google\\Protobuf\\": "src/GPBMetadata/Google/Protobuf" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "proto library for PHP", + "homepage": "https://developers.google.com/protocol-buffers/", + "keywords": [ + "proto" + ], + "support": { + "source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.33.0" + }, + "time": "2025-10-15T20:10:28+00:00" + }, + { + "name": "grpc/grpc", + "version": "1.74.0", + "source": { + "type": "git", + "url": "https://github.com/grpc/grpc-php.git", + "reference": "32bf4dba256d60d395582fb6e4e8d3936bcdb713" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/grpc/grpc-php/zipball/32bf4dba256d60d395582fb6e4e8d3936bcdb713", + "reference": "32bf4dba256d60d395582fb6e4e8d3936bcdb713", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "google/auth": "^v1.3.0" + }, + "suggest": { + "ext-protobuf": "For better performance, install the protobuf C extension.", + "google/protobuf": "To get started using grpc quickly, install the native protobuf library." + }, + "type": "library", + "autoload": { + "psr-4": { + "Grpc\\": "src/lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "gRPC library for PHP", + "homepage": "https://grpc.io", + "keywords": [ + "rpc" + ], + "support": { + "source": "https://github.com/grpc/grpc-php/tree/v1.74.0" + }, + "time": "2025-07-24T20:02:16+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.10.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", + "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^2.3", + "guzzlehttp/psr7": "^2.8", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "guzzle/client-integration-tests": "3.0.2", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.10.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2025-08-23T22:36:01+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "481557b130ef3790cf82b713667b43030dc9c957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/481557b130ef3790cf82b713667b43030dc9c957", + "reference": "481557b130ef3790cf82b713667b43030dc9c957", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.44 || ^9.6.25" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.3.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2025-08-22T14:34:08+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.8.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "21dc724a0583619cd1652f673303492272778051" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051", + "reference": "21dc724a0583619cd1652f673303492272778051", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.44 || ^9.6.25" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.8.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2025-08-23T21:21:41+00:00" + }, + { + "name": "league/flysystem", + "version": "3.30.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "c139fd65c1f796b926f4aec0df37f6caa959a8da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/c139fd65c1f796b926f4aec0df37f6caa959a8da", + "reference": "c139fd65c1f796b926f4aec0df37f6caa959a8da", + "shasum": "" + }, + "require": { + "league/flysystem-local": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "conflict": { + "async-aws/core": "<1.19.0", + "async-aws/s3": "<1.14.0", + "aws/aws-sdk-php": "3.209.31 || 3.210.0", + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1", + "phpseclib/phpseclib": "3.0.15", + "symfony/http-client": "<5.2" + }, + "require-dev": { + "async-aws/s3": "^1.5 || ^2.0", + "async-aws/simple-s3": "^1.1 || ^2.0", + "aws/aws-sdk-php": "^3.295.10", + "composer/semver": "^3.0", + "ext-fileinfo": "*", + "ext-ftp": "*", + "ext-mongodb": "^1.3|^2", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.5", + "google/cloud-storage": "^1.23", + "guzzlehttp/psr7": "^2.6", + "microsoft/azure-storage-blob": "^1.1", + "mongodb/mongodb": "^1.2|^2", + "phpseclib/phpseclib": "^3.0.36", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5.11|^10.0", + "sabre/dav": "^4.6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "File storage abstraction for PHP", + "keywords": [ + "WebDAV", + "aws", + "cloud", + "file", + "files", + "filesystem", + "filesystems", + "ftp", + "s3", + "sftp", + "storage" + ], + "support": { + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/3.30.1" + }, + "time": "2025-10-20T15:35:26+00:00" + }, + { + "name": "league/flysystem-aws-s3-v3", + "version": "3.30.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git", + "reference": "d286e896083bed3190574b8b088b557b59eb66f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/d286e896083bed3190574b8b088b557b59eb66f5", + "reference": "d286e896083bed3190574b8b088b557b59eb66f5", + "shasum": "" + }, + "require": { + "aws/aws-sdk-php": "^3.295.10", + "league/flysystem": "^3.10.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "conflict": { + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\AwsS3V3\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "AWS S3 filesystem adapter for Flysystem.", + "keywords": [ + "Flysystem", + "aws", + "file", + "files", + "filesystem", + "s3", + "storage" + ], + "support": { + "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.30.1" + }, + "time": "2025-10-20T15:27:33+00:00" + }, + { + "name": "league/flysystem-azure-blob-storage", + "version": "3.30.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-azure-blob-storage.git", + "reference": "731d07713f3541f3f204817117f27d4c7f175c5a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-azure-blob-storage/zipball/731d07713f3541f3f204817117f27d4c7f175c5a", + "reference": "731d07713f3541f3f204817117f27d4c7f175c5a", + "shasum": "" + }, + "require": { + "league/flysystem": "^3.10.0", + "microsoft/azure-storage-blob": "^1.1", + "php": "^8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\AzureBlobStorage\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "support": { + "source": "https://github.com/thephpleague/flysystem-azure-blob-storage/tree/3.30.0" + }, + "abandoned": "azure-oss/storage-blob-flysystem", + "time": "2025-02-09T18:52:59+00:00" + }, + { + "name": "league/flysystem-google-cloud-storage", + "version": "3.30.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-google-cloud-storage.git", + "reference": "2d36f1a050fe70bf21d8aa75275963f9ca2e16ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-google-cloud-storage/zipball/2d36f1a050fe70bf21d8aa75275963f9ca2e16ea", + "reference": "2d36f1a050fe70bf21d8aa75275963f9ca2e16ea", + "shasum": "" + }, + "require": { + "google/cloud-storage": "^1.23", + "league/flysystem": "^3.10.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\GoogleCloudStorage\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Google Cloud Storage adapter for Flysystem.", + "keywords": [ + "Flysystem", + "filesystem", + "gcs", + "google cloud storage" + ], + "support": { + "source": "https://github.com/thephpleague/flysystem-google-cloud-storage/tree/3.30.1" + }, + "time": "2025-10-20T15:27:33+00:00" + }, + { + "name": "league/flysystem-local", + "version": "3.30.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-local.git", + "reference": "6691915f77c7fb69adfb87dcd550052dc184ee10" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/6691915f77c7fb69adfb87dcd550052dc184ee10", + "reference": "6691915f77c7fb69adfb87dcd550052dc184ee10", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "league/flysystem": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\Local\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Local filesystem adapter for Flysystem.", + "keywords": [ + "Flysystem", + "file", + "files", + "filesystem", + "local" + ], + "support": { + "source": "https://github.com/thephpleague/flysystem-local/tree/3.30.0" + }, + "time": "2025-05-21T10:34:19+00:00" + }, + { + "name": "league/flysystem-sftp-v3", + "version": "3.30.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-sftp-v3.git", + "reference": "93f297837b5052f4cfee601b2e0352addd956448" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-sftp-v3/zipball/93f297837b5052f4cfee601b2e0352addd956448", + "reference": "93f297837b5052f4cfee601b2e0352addd956448", + "shasum": "" + }, + "require": { + "league/flysystem": "^3.0.14", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2", + "phpseclib/phpseclib": "^3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\PhpseclibV3\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "SFTP filesystem adapter for Flysystem.", + "keywords": [ + "Flysystem", + "file", + "files", + "filesystem", + "sftp" + ], + "support": { + "source": "https://github.com/thephpleague/flysystem-sftp-v3/tree/3.30.0" + }, + "time": "2025-04-17T15:49:35+00:00" + }, + { + "name": "league/flysystem-webdav", + "version": "3.30.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-webdav.git", + "reference": "bfbd39983edc6fa147f65a7227a1f0883704d821" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-webdav/zipball/bfbd39983edc6fa147f65a7227a1f0883704d821", + "reference": "bfbd39983edc6fa147f65a7227a1f0883704d821", + "shasum": "" + }, + "require": { + "league/flysystem": "^3.6.0", + "php": "^8.0.2", + "sabre/dav": "^4.6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\WebDAV\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "WebDAV filesystem adapter for Flysystem.", + "keywords": [ + "Flysystem", + "WebDAV", + "file", + "files", + "filesystem" + ], + "support": { + "source": "https://github.com/thephpleague/flysystem-webdav/tree/3.30.0" + }, + "time": "2025-01-26T13:57:48+00:00" + }, + { + "name": "league/mime-type-detection", + "version": "1.16.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/mime-type-detection.git", + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/2d6702ff215bf922936ccc1ad31007edc76451b9", + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "phpstan/phpstan": "^0.12.68", + "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\MimeTypeDetection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Mime-type detection for Flysystem", + "support": { + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.16.0" + }, + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2024-09-21T08:32:55+00:00" + }, + { + "name": "microsoft/azure-storage-blob", + "version": "1.5.4", + "source": { + "type": "git", + "url": "https://github.com/Azure/azure-storage-blob-php.git", + "reference": "1023ce1dbf062351a32ca5ec72ad1fd4a504f1bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Azure/azure-storage-blob-php/zipball/1023ce1dbf062351a32ca5ec72ad1fd4a504f1bf", + "reference": "1023ce1dbf062351a32ca5ec72ad1fd4a504f1bf", + "shasum": "" + }, + "require": { + "microsoft/azure-storage-common": "~1.5", + "php": ">=5.6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "MicrosoftAzure\\Storage\\Blob\\": "src/Blob" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Azure Storage PHP Client Library", + "email": "dmsh@microsoft.com" + } + ], + "description": "This project provides a set of PHP client libraries that make it easy to access Microsoft Azure Storage Blob APIs.", + "keywords": [ + "azure", + "blob", + "php", + "sdk", + "storage" + ], + "support": { + "issues": "https://github.com/Azure/azure-storage-blob-php/issues", + "source": "https://github.com/Azure/azure-storage-blob-php/tree/v1.5.4" + }, + "time": "2022-09-02T02:13:06+00:00" + }, + { + "name": "microsoft/azure-storage-common", + "version": "1.5.2", + "source": { + "type": "git", + "url": "https://github.com/Azure/azure-storage-common-php.git", + "reference": "8ca7b1bf4c9ca7c663e75a02a0035b05b37196a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Azure/azure-storage-common-php/zipball/8ca7b1bf4c9ca7c663e75a02a0035b05b37196a0", + "reference": "8ca7b1bf4c9ca7c663e75a02a0035b05b37196a0", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "~6.0|^7.0", + "php": ">=5.6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "MicrosoftAzure\\Storage\\Common\\": "src/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Azure Storage PHP Client Library", + "email": "dmsh@microsoft.com" + } + ], + "description": "This project provides a set of common code shared by Azure Storage Blob, Table, Queue and File PHP client libraries.", + "keywords": [ + "azure", + "common", + "php", + "sdk", + "storage" + ], + "support": { + "issues": "https://github.com/Azure/azure-storage-common-php/issues", + "source": "https://github.com/Azure/azure-storage-common-php/tree/v1.5.2" + }, + "time": "2021-10-09T03:03:47+00:00" + }, + { + "name": "monolog/monolog", + "version": "3.9.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/10d85740180ecba7896c87e06a166e0c95a0e3b6", + "reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2 || ^2.0", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "php-console/php-console": "^3.1.8", + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^10.5.17 || ^11.0.7", + "predis/predis": "^1.1 || ^2", + "rollbar/rollbar": "^4.0", + "ruflin/elastica": "^7 || ^8", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/3.9.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2025-03-24T10:02:05+00:00" + }, + { + "name": "mtdowling/jmespath.php", + "version": "2.8.0", + "source": { + "type": "git", + "url": "https://github.com/jmespath/jmespath.php.git", + "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/a2a865e05d5f420b50cc2f85bb78d565db12a6bc", + "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "symfony/polyfill-mbstring": "^1.17" + }, + "require-dev": { + "composer/xdebug-handler": "^3.0.3", + "phpunit/phpunit": "^8.5.33" + }, + "bin": [ + "bin/jp.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "files": [ + "src/JmesPath.php" + ], + "psr-4": { + "JmesPath\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Declaratively specify how to extract elements from a JSON document", + "keywords": [ + "json", + "jsonpath" + ], + "support": { + "issues": "https://github.com/jmespath/jmespath.php/issues", + "source": "https://github.com/jmespath/jmespath.php/tree/2.8.0" + }, + "time": "2024-09-04T18:46:31+00:00" + }, + { + "name": "paragonie/constant_time_encoding", + "version": "v3.1.3", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", + "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", + "shasum": "" + }, + "require": { + "php": "^8" + }, + "require-dev": { + "infection/infection": "^0", + "nikic/php-fuzzer": "^0", + "phpunit/phpunit": "^9|^10|^11", + "vimeo/psalm": "^4|^5|^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "time": "2025-09-24T15:06:41+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.47", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "9d6ca36a6c2dd434765b1071b2644a1c683b385d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/9d6ca36a6c2dd434765b1071b2644a1c683b385d", + "reference": "9d6ca36a6c2dd434765b1071b2644a1c683b385d", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2|^3", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.47" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2025-10-06T01:07:24+00:00" + }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/3.0.0" + }, + "time": "2021-02-03T23:26:27+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "ramsey/collection", + "version": "2.1.1", + "source": { + "type": "git", + "url": "https://github.com/ramsey/collection.git", + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/collection/zipball/344572933ad0181accbf4ba763e85a0306a8c5e2", + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.45", + "fakerphp/faker": "^1.24", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^2.1", + "mockery/mockery": "^1.6", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.4", + "phpspec/prophecy-phpunit": "^2.3", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-mockery": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.5", + "ramsey/coding-standard": "^2.3", + "ramsey/conventional-commits": "^1.6", + "roave/security-advisories": "dev-latest" + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/2.1.1" + }, + "time": "2025-03-22T05:38:12+00:00" + }, + { + "name": "ramsey/uuid", + "version": "4.9.1", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "81f941f6f729b1e3ceea61d9d014f8b6c6800440" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/81f941f6f729b1e3ceea61d9d014f8b6c6800440", + "reference": "81f941f6f729b1e3ceea61d9d014f8b6c6800440", + "shasum": "" + }, + "require": { + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14", + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.25", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "ergebnis/composer-normalize": "^2.47", + "mockery/mockery": "^1.6", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.6", + "php-mock/php-mock-mockery": "^1.5", + "php-parallel-lint/php-parallel-lint": "^1.4.0", + "phpbench/phpbench": "^1.2.14", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-mockery": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6", + "slevomat/coding-standard": "^8.18", + "squizlabs/php_codesniffer": "^3.13" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.9.1" + }, + "time": "2025-09-04T20:59:21+00:00" + }, + { + "name": "rize/uri-template", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/rize/UriTemplate.git", + "reference": "56f374a9a42c7c3998f8b55b6b21b224de90c58b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rize/UriTemplate/zipball/56f374a9a42c7c3998f8b55b6b21b224de90c58b", + "reference": "56f374a9a42c7c3998f8b55b6b21b224de90c58b", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.63", + "phpstan/phpstan": "^1.12", + "phpunit/phpunit": "~10.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Rize\\": "src/Rize" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marut K", + "homepage": "http://twitter.com/rezigned" + } + ], + "description": "PHP URI Template (RFC 6570) supports both expansion & extraction", + "keywords": [ + "RFC 6570", + "template", + "uri" + ], + "support": { + "issues": "https://github.com/rize/UriTemplate/issues", + "source": "https://github.com/rize/UriTemplate/tree/0.4.0" + }, + "funding": [ + { + "url": "https://www.paypal.me/rezigned", + "type": "custom" + }, + { + "url": "https://github.com/rezigned", + "type": "github" + }, + { + "url": "https://opencollective.com/rize-uri-template", + "type": "open_collective" + } + ], + "time": "2024-11-27T12:13:42+00:00" + }, + { + "name": "sabre/dav", + "version": "4.7.0", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/dav.git", + "reference": "074373bcd689a30bcf5aaa6bbb20a3395964ce7a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/dav/zipball/074373bcd689a30bcf5aaa6bbb20a3395964ce7a", + "reference": "074373bcd689a30bcf5aaa6bbb20a3395964ce7a", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-date": "*", + "ext-dom": "*", + "ext-iconv": "*", + "ext-json": "*", + "ext-mbstring": "*", + "ext-pcre": "*", + "ext-simplexml": "*", + "ext-spl": "*", + "lib-libxml": ">=2.7.0", + "php": "^7.1.0 || ^8.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "sabre/event": "^5.0", + "sabre/http": "^5.0.5", + "sabre/uri": "^2.0", + "sabre/vobject": "^4.2.1", + "sabre/xml": "^2.0.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.19", + "monolog/monolog": "^1.27 || ^2.0", + "phpstan/phpstan": "^0.12 || ^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6" + }, + "suggest": { + "ext-curl": "*", + "ext-imap": "*", + "ext-pdo": "*" + }, + "bin": [ + "bin/sabredav", + "bin/naturalselection" + ], + "type": "library", + "autoload": { + "psr-4": { + "Sabre\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "WebDAV Framework for PHP", + "homepage": "http://sabre.io/", + "keywords": [ + "CalDAV", + "CardDAV", + "WebDAV", + "framework", + "iCalendar" + ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/dav/issues", + "source": "https://github.com/fruux/sabre-dav" + }, + "time": "2024-10-29T11:46:02+00:00" + }, + { + "name": "sabre/event", + "version": "5.1.7", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/event.git", + "reference": "86d57e305c272898ba3c28e9bd3d65d5464587c2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/event/zipball/86d57e305c272898ba3c28e9bd3d65d5464587c2", + "reference": "86d57e305c272898ba3c28e9bd3d65d5464587c2", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.17.1||^3.63", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6" + }, + "type": "library", + "autoload": { + "files": [ + "lib/coroutine.php", + "lib/Loop/functions.php", + "lib/Promise/functions.php" + ], + "psr-4": { + "Sabre\\Event\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "sabre/event is a library for lightweight event-based programming", + "homepage": "http://sabre.io/event/", + "keywords": [ + "EventEmitter", + "async", + "coroutine", + "eventloop", + "events", + "hooks", + "plugin", + "promise", + "reactor", + "signal" + ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/event/issues", + "source": "https://github.com/fruux/sabre-event" + }, + "time": "2024-08-27T11:23:05+00:00" + }, + { + "name": "sabre/http", + "version": "5.1.13", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/http.git", + "reference": "7c2a14097d1a0de2347dcbdc91a02f38e338f4db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/http/zipball/7c2a14097d1a0de2347dcbdc91a02f38e338f4db", + "reference": "7c2a14097d1a0de2347dcbdc91a02f38e338f4db", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-curl": "*", + "ext-mbstring": "*", + "php": "^7.1 || ^8.0", + "sabre/event": ">=4.0 <6.0", + "sabre/uri": "^2.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.17.1||3.63.2", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6" + }, + "suggest": { + "ext-curl": " to make http requests with the Client class" + }, + "type": "library", + "autoload": { + "files": [ + "lib/functions.php" + ], + "psr-4": { + "Sabre\\HTTP\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "The sabre/http library provides utilities for dealing with http requests and responses. ", + "homepage": "https://github.com/fruux/sabre-http", + "keywords": [ + "http" + ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/http/issues", + "source": "https://github.com/fruux/sabre-http" + }, + "time": "2025-09-09T10:21:47+00:00" + }, + { + "name": "sabre/uri", + "version": "2.3.4", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/uri.git", + "reference": "b76524c22de90d80ca73143680a8e77b1266c291" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/uri/zipball/b76524c22de90d80ca73143680a8e77b1266c291", + "reference": "b76524c22de90d80ca73143680a8e77b1266c291", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.63", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^1.12", + "phpstan/phpstan-phpunit": "^1.4", + "phpstan/phpstan-strict-rules": "^1.6", + "phpunit/phpunit": "^9.6" + }, + "type": "library", + "autoload": { + "files": [ + "lib/functions.php" + ], + "psr-4": { + "Sabre\\Uri\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "Functions for making sense out of URIs.", + "homepage": "http://sabre.io/uri/", + "keywords": [ + "rfc3986", + "uri", + "url" + ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/uri/issues", + "source": "https://github.com/fruux/sabre-uri" + }, + "time": "2024-08-27T12:18:16+00:00" + }, + { + "name": "sabre/vobject", + "version": "4.5.7", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/vobject.git", + "reference": "ff22611a53782e90c97be0d0bc4a5f98a5c0a12c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/vobject/zipball/ff22611a53782e90c97be0d0bc4a5f98a5c0a12c", + "reference": "ff22611a53782e90c97be0d0bc4a5f98a5c0a12c", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^7.1 || ^8.0", + "sabre/xml": "^2.1 || ^3.0 || ^4.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.17.1", + "phpstan/phpstan": "^0.12 || ^1.12 || ^2.0", + "phpunit/php-invoker": "^2.0 || ^3.1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6" + }, + "suggest": { + "hoa/bench": "If you would like to run the benchmark scripts" + }, + "bin": [ + "bin/vobject", + "bin/generate_vcards" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Sabre\\VObject\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + }, + { + "name": "Dominik Tobschall", + "email": "dominik@fruux.com", + "homepage": "http://tobschall.de/", + "role": "Developer" + }, + { + "name": "Ivan Enderlin", + "email": "ivan.enderlin@hoa-project.net", + "homepage": "http://mnt.io/", + "role": "Developer" + } + ], + "description": "The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects", + "homepage": "http://sabre.io/vobject/", + "keywords": [ + "availability", + "freebusy", + "iCalendar", + "ical", + "ics", + "jCal", + "jCard", + "recurrence", + "rfc2425", + "rfc2426", + "rfc2739", + "rfc4770", + "rfc5545", + "rfc5546", + "rfc6321", + "rfc6350", + "rfc6351", + "rfc6474", + "rfc6638", + "rfc6715", + "rfc6868", + "vCalendar", + "vCard", + "vcf", + "xCal", + "xCard" + ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/vobject/issues", + "source": "https://github.com/fruux/sabre-vobject" + }, + "time": "2025-04-17T09:22:48+00:00" + }, + { + "name": "sabre/xml", + "version": "2.2.11", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/xml.git", + "reference": "01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/xml/zipball/01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc", + "reference": "01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlreader": "*", + "ext-xmlwriter": "*", + "lib-libxml": ">=2.6.20", + "php": "^7.1 || ^8.0", + "sabre/uri": ">=1.0,<3.0.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.17.1||3.63.2", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6" + }, + "type": "library", + "autoload": { + "files": [ + "lib/Deserializer/functions.php", + "lib/Serializer/functions.php" + ], + "psr-4": { + "Sabre\\Xml\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + }, + { + "name": "Markus Staab", + "email": "markus.staab@redaxo.de", + "role": "Developer" + } + ], + "description": "sabre/xml is an XML library that you may not hate.", + "homepage": "https://sabre.io/xml/", + "keywords": [ + "XMLReader", + "XMLWriter", + "dom", + "xml" + ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/xml/issues", + "source": "https://github.com/fruux/sabre-xml" + }, + "time": "2024-09-06T07:37:46+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-23T08:48:59+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=7.4" + }, + "platform-dev": {}, + "plugin-api-version": "2.6.0" +} diff --git a/flysystem-offload.php b/flysystem-offload.php new file mode 100644 index 0000000..6da53c8 --- /dev/null +++ b/flysystem-offload.php @@ -0,0 +1,14 @@ +pluginFile = $pluginFile; + } + + public function boot(): void + { + add_action('admin_menu', [$this, 'registerPage']); + add_action('admin_init', [$this, 'registerSettings']); + add_action('admin_enqueue_scripts', [$this, 'enqueueAssets']); + } + + public function enqueueAssets(): void + { + $screen = get_current_screen(); + if (! $screen || $screen->id !== 'settings_page_flysystem-offload') { + return; + } + + wp_enqueue_script( + 'flysystem-offload-settings', + plugins_url('assets/admin-settings.js', $this->pluginFile), + ['jquery'], + '0.1.0', + true + ); + } + + public function registerPage(): void + { + add_options_page( + __('Flysystem Offload', 'flysystem-offload'), + __('Flysystem Offload', 'flysystem-offload'), + 'manage_options', + 'flysystem-offload', + [$this, 'render'] + ); + } + + public function registerSettings(): void + { + register_setting( + 'flysystem_offload', + 'flysystem_offload_settings', + [ + 'sanitize_callback' => [$this, 'sanitizeSettings'], + ] + ); + + add_settings_section( + 'flysystem_offload_general', + __('Configuración general', 'flysystem-offload'), + '__return_false', + 'flysystem-offload' + ); + + add_settings_field( + 'adapter', + __('Adaptador activo', 'flysystem-offload'), + [$this, 'renderAdapterField'], + 'flysystem-offload', + 'flysystem_offload_general' + ); + + add_settings_field( + 'base_prefix', + __('Prefijo de almacenamiento', 'flysystem-offload'), + [$this, 'renderBasePrefixField'], + 'flysystem-offload', + 'flysystem_offload_general' + ); + + add_settings_section( + 'flysystem_offload_s3', + __('Amazon S3 / Compatible', 'flysystem-offload'), + function () { + echo '

' . esc_html__('Proporciona credenciales de un bucket S3 o compatible (MinIO, DigitalOcean Spaces, etc.).', 'flysystem-offload') . '

'; + }, + 'flysystem-offload' + ); + + add_settings_field( + 's3_access_key', + __('Access Key', 'flysystem-offload'), + [$this, 'renderS3Field'], + 'flysystem-offload', + 'flysystem_offload_s3', + ['key' => 'access_key', 'type' => 'text'] + ); + + add_settings_field( + 's3_secret_key', + __('Secret Key', 'flysystem-offload'), + [$this, 'renderS3Field'], + 'flysystem-offload', + 'flysystem_offload_s3', + ['key' => 'secret_key', 'type' => 'password'] + ); + + add_settings_field( + 's3_region', + __('Región', 'flysystem-offload'), + [$this, 'renderS3Field'], + 'flysystem-offload', + 'flysystem_offload_s3', + ['key' => 'region', 'type' => 'text', 'placeholder' => 'us-east-1'] + ); + + add_settings_field( + 's3_bucket', + __('Bucket', 'flysystem-offload'), + [$this, 'renderS3Field'], + 'flysystem-offload', + 'flysystem_offload_s3', + ['key' => 'bucket', 'type' => 'text'] + ); + + add_settings_field( + 's3_prefix', + __('Prefijo (opcional)', 'flysystem-offload'), + [$this, 'renderS3Field'], + 'flysystem-offload', + 'flysystem_offload_s3', + ['key' => 'prefix', 'type' => 'text', 'placeholder' => 'uploads'] + ); + + add_settings_field( + 's3_endpoint', + __('Endpoint personalizado', 'flysystem-offload'), + [$this, 'renderS3Field'], + 'flysystem-offload', + 'flysystem_offload_s3', + ['key' => 'endpoint', 'type' => 'text', 'placeholder' => 'https://nyc3.digitaloceanspaces.com'] + ); + + add_settings_field( + 's3_cdn_url', + __('URL CDN (opcional)', 'flysystem-offload'), + [$this, 'renderS3Field'], + 'flysystem-offload', + 'flysystem_offload_s3', + ['key' => 'cdn_url', 'type' => 'text', 'placeholder' => 'https://cdn.midominio.com'] + ); + } + + public function sanitizeSettings(array $input): array + { + $current = get_option('flysystem_offload_settings', []); + + $adapter = sanitize_key($input['adapter'] ?? $current['adapter'] ?? 'local'); + $basePrefix = trim($input['base_prefix'] ?? ''); + + $s3 = $current['adapters']['s3'] ?? []; + $inputS3 = $input['adapters']['s3'] ?? []; + + $secretRaw = $inputS3['secret_key'] ?? ''; + $secret = $secretRaw === '' ? ($s3['secret_key'] ?? '') : $secretRaw; + + $sanitizedS3 = [ + 'access_key' => sanitize_text_field($inputS3['access_key'] ?? $s3['access_key'] ?? ''), + 'secret_key' => sanitize_text_field($inputS3['secret_key'] ?? $s3['secret_key'] ?? ''), + 'region' => sanitize_text_field($inputS3['region'] ?? $s3['region'] ?? ''), + 'bucket' => sanitize_text_field($inputS3['bucket'] ?? $s3['bucket'] ?? ''), + 'prefix' => trim($inputS3['prefix'] ?? $s3['prefix'] ?? ''), + 'endpoint' => esc_url_raw($inputS3['endpoint'] ?? $s3['endpoint'] ?? ''), + 'cdn_url' => esc_url_raw($inputS3['cdn_url'] ?? $s3['cdn_url'] ?? ''), + ]; + + $current['adapter'] = $adapter; + $current['base_prefix'] = $basePrefix; + $current['adapters']['s3'] = $sanitizedS3; + + return $current; + } + + public function render(): void + { + ?> +
+

+
+ +
+
+ __('Local (fallback)', 'flysystem-offload'), + 's3' => 'Amazon S3 / Compatible', + 'sftp' => 'SFTP', + 'webdav' => 'WebDAV', + 'gcs' => 'Google Cloud Storage', + 'azure' => 'Azure Blob Storage', + 'googledrive' => 'Google Drive (beta)', + 'onedrive' => 'OneDrive (beta)', + 'dropbox' => 'Dropbox (beta)', + ]; + ?> + + + +

+ +

+ + + +

+ +

+ [ + 'key' => $settings['access_key'], + 'secret' => $settings['secret_key'] + ], + 'region' => $settings['region'], + 'version' => 'latest' + ]; + + if (!empty($settings['endpoint'])) { + $clientConfig['endpoint'] = $settings['endpoint']; + $clientConfig['use_path_style_endpoint'] = true; + } + + $client = new S3Client($clientConfig); + + return new AwsS3V3Adapter($client, $settings['bucket'], $settings['prefix'] ?? ''); + } catch (\Throwable $e) { + return new WP_Error('flysystem_offload_s3_error', $e->getMessage()); + } + } + + public function publicBaseUrl(array $settings): string + { + if (!empty($settings['cdn_url'])) { + return rtrim($settings['cdn_url'], '/'); + } + + $bucket = $settings['bucket']; + $region = $settings['region']; + + if ($region === 'us-east-1') { + return "https://{$bucket}.s3.amazonaws.com"; + } + + return "https://{$bucket}.s3.{$region}.amazonaws.com"; + } +} diff --git a/src/Filesystem/Adapters/SftpAdapter.php b/src/Filesystem/Adapters/SftpAdapter.php new file mode 100644 index 0000000..e69de29 diff --git a/src/Filesystem/Adapters/WebdavAdapter.php b/src/Filesystem/Adapters/WebdavAdapter.php new file mode 100644 index 0000000..e69de29 diff --git a/src/Filesystem/FilesystemFactory.php b/src/Filesystem/FilesystemFactory.php new file mode 100644 index 0000000..fa9ab47 --- /dev/null +++ b/src/Filesystem/FilesystemFactory.php @@ -0,0 +1,88 @@ +settings = $settings; + } + + public function make(): FilesystemOperator|WP_Error + { + $adapterKey = $this->settings['adapter'] ?? 'local'; + $config = $this->settings['adapters'][$adapterKey] ?? []; + + $adapter = $this->resolveAdapter($adapterKey); + + if (is_wp_error($adapter)) { + return $adapter; + } + + $validation = $adapter->validate($config); + if (is_wp_error($validation)) { + return $validation; + } + + $flyAdapter = $adapter->create($config); + if (is_wp_error($flyAdapter)) { + return $flyAdapter; + } + + return new Filesystem($flyAdapter); + } + + public function resolvePublicBaseUrl(string $adapterKey, array $settings): string + { + $adapter = $this->resolveAdapter($adapterKey); + + if (is_wp_error($adapter)) { + return content_url('/uploads'); + } + + return $adapter->publicBaseUrl($settings); + } + + private function resolveAdapter(string $adapterKey): AdapterInterface|WP_Error + { + return match ($adapterKey) { + 's3' => new S3Adapter(), + 'sftp' => new SftpAdapter(), + 'gcs' => new GoogleCloudAdapter(), + 'azure' => new AzureBlobAdapter(), + 'webdav' => new WebdavAdapter(), + 'googledrive' => new GoogleDriveAdapter(), // stub (dev) + 'onedrive' => new OneDriveAdapter(), // stub (dev) + 'dropbox' => new DropboxAdapter(), // stub (dev) + default => new class implements AdapterInterface { + public function create(array $settings) + { + return new \League\Flysystem\Local\LocalFilesystemAdapter(WP_CONTENT_DIR . '/flysystem-uploads'); + } + public function publicBaseUrl(array $settings): string + { + return content_url('/flysystem-uploads'); + } + public function validate(array $settings) + { + wp_mkdir_p(WP_CONTENT_DIR . '/flysystem-uploads'); + return true; + } + } + }; + } +} diff --git a/src/Filesystem/Traits/ValidatesOptionsTrait.php b/src/Filesystem/Traits/ValidatesOptionsTrait.php new file mode 100644 index 0000000..e69de29 diff --git a/src/Helpers/PathHelper.php b/src/Helpers/PathHelper.php new file mode 100644 index 0000000..afce594 --- /dev/null +++ b/src/Helpers/PathHelper.php @@ -0,0 +1,60 @@ +init(); + }); + } + + public static function instance(): self + { + return self::$instance ??= new self(); + } + + public static function activate(): void + { + $defaults = [ + 'adapter' => 'local', + 'base_prefix' => '', + 'adapters' => [ + 's3' => [ + 'access_key' => '', + 'secret_key' => '', + 'region' => '', + 'bucket' => '', + 'endpoint' => '', + 'cdn_url' => '' + ], + 'sftp' => [ + 'host' => '', + 'port' => 22, + 'username' => '', + 'password' => '', + 'root' => '/uploads' + ], + 'gcs' => [ + 'project_id' => '', + 'bucket' => '', + 'key_file_path' => '' + ], + 'azure' => [ + 'account_name' => '', + 'account_key' => '', + 'container' => '', + 'prefix' => '' + ], + 'webdav' => [ + 'base_uri' => '', + 'username' => '', + 'password' => '', + 'path_prefix' => '' + ], + 'googledrive' => [], + 'onedrive' => [], + 'dropbox' => [] + ] + ]; + + add_option('flysystem_offload_settings', $defaults); + } + + public static function deactivate(): void + { + if (in_array('fly', stream_get_wrappers(), true)) { + stream_wrapper_unregister('fly'); + } + } + + public function init(): void + { + $this->settings = get_option('flysystem_offload_settings', []); + + add_action( + 'update_option_flysystem_offload_settings', + function ($oldValue, $newValue) { + $this->settings = $newValue; + $this->filesystem = null; + $this->streamRegistered = false; + $this->registerStreamWrapper(); + }, + 10, + 2 + ); + + $this->registerStreamWrapper(); + + add_filter('upload_dir', [$this, 'filterUploadDir'], 20); + add_filter('wp_get_attachment_url', [$this, 'filterAttachmentUrl'], 20, 2); + add_filter('wp_get_attachment_metadata', [$this, 'filterAttachmentMetadata'], 20); + add_filter('wp_get_original_image_path', [$this, 'filterOriginalImagePath'], 20); + add_filter('wp_delete_file', [$this, 'handleDeleteFile'], 20); + add_action('delete_attachment', [$this, 'handleDeleteAttachment'], 20); + + add_action('switch_blog', function () { + $this->filesystem = null; + $this->streamRegistered = false; + $this->settings = get_option('flysystem_offload_settings', []); + $this->registerStreamWrapper(); + }); + + if (is_admin()) { + (new SettingsPage(self::$pluginFile))->boot(); + } + + if (defined('WP_CLI') && WP_CLI) { + \WP_CLI::add_command('flysystem-offload health-check', [Admin\HealthCheck::class, 'run']); + } + } + + public function getFilesystem(): FilesystemOperator + { + if (!$this->filesystem) { + $factory = new FilesystemFactory($this->settings); + $result = $factory->make(); + + if (is_wp_error($result)) { + throw new \RuntimeException($result->get_error_message()); + } + + $this->filesystem = $result; + } + + return $this->filesystem; + } + + private function registerStreamWrapper(): void + { + if ($this->streamRegistered) { + return; + } + + try { + FlysystemStreamWrapper::register($this->getFilesystem(), 'fly', PathHelper::normalizePrefix($this->settings['base_prefix'] ?? '')); + $this->streamRegistered = true; + } catch (\Throwable $e) { + error_log('[Flysystem Offload] No se pudo registrar el stream wrapper: ' . $e->getMessage()); + } + } + + public function filterUploadDir(array $dirs): array + { + $remoteBase = $this->getRemoteUrlBase(); + $prefix = PathHelper::normalizePrefix($this->settings['base_prefix'] ?? ''); + $subdir = $dirs['subdir'] ?? ''; + + $dirs['path'] = "fly://{$prefix}{$subdir}"; + $dirs['basedir'] = "fly://{$prefix}"; + $dirs['url'] = trailingslashit($remoteBase) . ltrim($subdir, '/'); + $dirs['baseurl'] = $remoteBase; + + return $dirs; + } + + public function filterAttachmentUrl(string $url, int $postId): string + { + $localBase = trailingslashit(wp_get_upload_dir()['baseurl']); + $remoteBase = trailingslashit($this->getRemoteUrlBase()); + + return str_replace($localBase, $remoteBase, $url); + } + + public function filterAttachmentMetadata(array $metadata): array + { + if (!empty($metadata['file'])) { + $metadata['file'] = PathHelper::stripProtocol($metadata['file']); + } + + if (!empty($metadata['sizes'])) { + foreach ($metadata['sizes'] as &$size) { + if (!empty($size['file'])) { + $size['file'] = ltrim($size['file'], '/'); + } + } + } + + return $metadata; + } + + public function filterOriginalImagePath(string $path): string + { + return PathHelper::ensureFlyProtocol($path); + } + + public function handleDeleteFile(string $file): string|false + { + $flyPath = PathHelper::stripProtocol($file); + + try { + $this->getFilesystem()->delete($flyPath); + } catch (\Throwable $e) { + error_log('[Flysystem Offload] Error al borrar archivo: ' . $flyPath . ' - ' . $e->getMessage()); + } + + return false; + } + + public function handleDeleteAttachment(int $postId): void + { + $files = PathHelper::collectFilesFromAttachment($postId); + + foreach ($files as $relativePath) { + try { + $this->getFilesystem()->delete($relativePath); + } catch (\Throwable $e) { + error_log('[Flysystem Offload] Error al borrar attachment: ' . $relativePath . ' - ' . $e->getMessage()); + } + } + } + + private function getRemoteUrlBase(): string + { + $adapterKey = $this->settings['adapter'] ?? 'local'; + $config = $this->settings['adapters'][$adapterKey] ?? []; + + return (new FilesystemFactory($this->settings))->resolvePublicBaseUrl($adapterKey, $config); + } +} diff --git a/src/StreamWrapper/FlysystemStreamWrapper.php b/src/StreamWrapper/FlysystemStreamWrapper.php new file mode 100644 index 0000000..4d15757 --- /dev/null +++ b/src/StreamWrapper/FlysystemStreamWrapper.php @@ -0,0 +1,255 @@ +protocol = strtok($path, ':'); + $this->path = $path; + $this->mode = $mode; + $this->flyPath = $this->resolveFlyPath($path); + + $filesystem = $this->filesystem(); + + if (strpbrk($mode, 'waxc')) { + $this->stream = fopen('php://temp', str_contains($mode, 'b') ? 'w+b' : 'w+'); + + if (str_contains($mode, 'a') && $filesystem->fileExists($this->flyPath)) { + $contents = $filesystem->readStream($this->flyPath); + stream_copy_to_stream($contents, $this->stream); + fclose($contents); + } + + rewind($this->stream); + return true; + } + + try { + $resource = $filesystem->readStream($this->flyPath); + $this->stream = $resource; + return is_resource($resource); + } catch (UnableToReadFile $e) { + return false; + } + } + + public function stream_read(int $count): string|false + { + return fread($this->stream, $count); + } + + public function stream_write(string $data): int|false + { + return fwrite($this->stream, $data); + } + + public function stream_flush(): bool + { + if (!strpbrk($this->mode, 'waxc')) { + return true; + } + + $filesystem = $this->filesystem(); + + try { + rewind($this->stream); + $filesystem->writeStream($this->flyPath, $this->stream); + return true; + } catch (UnableToWriteFile $e) { + error_log('[Flysystem Offload] Unable to flush stream: ' . $e->getMessage()); + return false; + } + } + + public function stream_close(): void + { + $this->stream_flush(); + + if (is_resource($this->stream)) { + fclose($this->stream); + } + } + + public function stream_stat(): array|false + { + return $this->url_stat($this->path, 0); + } + + public function url_stat(string $path, int $flags): array|false + { + $filesystem = $this->filesystem(); + $flyPath = $this->resolveFlyPath($path); + + try { + if (!$filesystem->fileExists($flyPath) && !$filesystem->directoryExists($flyPath)) { + if ($flags & STREAM_URL_STAT_QUIET) { + return false; + } + trigger_error("File or directory not found: {$path}", E_USER_WARNING); + return false; + } + + $isDir = $filesystem->directoryExists($flyPath); + $size = $isDir ? 0 : $filesystem->fileSize($flyPath); + $mtime = $filesystem->lastModified($flyPath); + + return [ + 'dev' => 0, + 'ino' => 0, + 'mode' => $isDir ? 0040777 : 0100777, + 'nlink' => 0, + 'uid' => 0, + 'gid' => 0, + 'rdev' => 0, + 'size' => $size, + 'atime' => $mtime, + 'mtime' => $mtime, + 'ctime' => $mtime, + 'blksize' => -1, + 'blocks' => -1 + ]; + } catch (FilesystemException $e) { + if (!($flags & STREAM_URL_STAT_QUIET)) { + trigger_error($e->getMessage(), E_USER_WARNING); + } + return false; + } + } + + public function unlink(string $path): bool + { + $filesystem = $this->filesystem(); + $flyPath = $this->resolveFlyPath($path); + + try { + $filesystem->delete($flyPath); + return true; + } catch (UnableToDeleteFile $e) { + return false; + } + } + + public function mkdir(string $path, int $mode, int $options): bool + { + $filesystem = $this->filesystem(); + $flyPath = $this->resolveFlyPath($path); + + try { + $filesystem->createDirectory($flyPath); + return true; + } catch (FilesystemException $e) { + return false; + } + } + + public function rmdir(string $path, int $options): bool + { + $filesystem = $this->filesystem(); + $flyPath = $this->resolveFlyPath($path); + + try { + $filesystem->deleteDirectory($flyPath); + return true; + } catch (FilesystemException $e) { + return false; + } + } + + public function dir_opendir(string $path, int $options): bool + { + $this->protocol = strtok($path, ':'); + $this->flyPath = $this->resolveFlyPath($path); + $this->stream = $this->filesystem()->listContents($this->flyPath, false)->getIterator(); + + return true; + } + + public function dir_readdir(): string|false + { + if ($this->stream instanceof \Iterator) { + if ($this->stream->valid()) { + $current = $this->stream->current(); + $this->stream->next(); + return $current['basename'] ?? $current['path'] ?? false; + } + } + + return false; + } + + public function dir_rewinddir(): bool + { + if ($this->stream instanceof \Iterator) { + $this->stream->rewind(); + return true; + } + + return false; + } + + public function dir_closedir(): bool + { + $this->stream = null; + return true; + } + + public function rename(string $oldPath, string $newPath): bool + { + $filesystem = $this->filesystem(); + $from = $this->resolveFlyPath($oldPath); + $to = $this->resolveFlyPath($newPath); + + try { + $filesystem->move($from, $to); + return true; + } catch (FilesystemException $e) { + return false; + } + } + + private function filesystem(): FilesystemOperator + { + if (!isset(self::$filesystems[$this->protocol])) { + throw new \RuntimeException('No filesystem registered for protocol: ' . $this->protocol); + } + + return self::$filesystems[$this->protocol]; + } + + private function resolveFlyPath(string $path): string + { + $protocol = strtok($path, ':'); + $prefix = self::$prefixes[$protocol] ?? ''; + $raw = preg_replace('#^[^:]+://#', '', $path); + + return ltrim($prefix . ltrim($raw, '/'), '/'); + } +}