diff --git a/composer.json b/composer.json index c49318b..5c4d624 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ } ], "require": { - "league/flysystem": "^3.7", + "league/flysystem": "^3.16", "ext-json": "*", "guzzlehttp/guzzle": "^7.4", "league/mime-type-detection": "^1.11" diff --git a/src/BunnyCDNAdapter.php b/src/BunnyCDNAdapter.php index 00f0735..db40608 100644 --- a/src/BunnyCDNAdapter.php +++ b/src/BunnyCDNAdapter.php @@ -19,6 +19,7 @@ use League\Flysystem\UnableToDeleteDirectory; use League\Flysystem\UnableToDeleteFile; use League\Flysystem\UnableToMoveFile; +use League\Flysystem\UnableToProvideChecksum; use League\Flysystem\UnableToReadFile; use League\Flysystem\UnableToRetrieveMetadata; use League\Flysystem\UnableToSetVisibility; @@ -493,7 +494,26 @@ public function fileExists(string $path): bool */ public function checksum(string $path, Config $config): string { - return $this->calculateChecksumFromStream($path, $config); + // for compatibility reasons, the default checksum algorithm is md5 + $algo = $config->get('checksum_algo', 'md5'); + + if ($algo !== 'sha256') { + return $this->calculateChecksumFromStream($path, $config); + } + + try { + $file = $this->getObject($path); + } catch (UnableToReadFile $exception) { + throw new UnableToProvideChecksum($exception->reason(), $path, $exception); + } + + $metaData = $file->extraMetadata(); + + if (empty($metaData['checksum']) || ! is_string($metaData['checksum'])) { + throw new UnableToProvideChecksum('Checksum not available.', $path); + } + + return \strtolower($metaData['checksum']); } /** diff --git a/tests/ClientDI_Example.php b/tests/ClientDI_Example.php index 8f2fcba..4e67c32 100644 --- a/tests/ClientDI_Example.php +++ b/tests/ClientDI_Example.php @@ -2,6 +2,10 @@ use PlatformCommunity\Flysystem\BunnyCDN\BunnyCDNRegion; +global $storage_zone; +global $api_key; +global $region; + // $storage_zone = 'testing_storage_zone'; // $api_key = 'testing_api_key'; // $region = BunnyCDNRegion::DEFAULT; diff --git a/tests/FlysystemTest.php b/tests/FlysystemAdapterTest.php similarity index 79% rename from tests/FlysystemTest.php rename to tests/FlysystemAdapterTest.php index f8d1da6..cb57342 100644 --- a/tests/FlysystemTest.php +++ b/tests/FlysystemAdapterTest.php @@ -2,6 +2,7 @@ namespace PlatformCommunity\Flysystem\BunnyCDN\Tests; +use Faker\Factory; use League\Flysystem\AdapterTestUtilities\FilesystemAdapterTestCase; use League\Flysystem\Config; use League\Flysystem\Filesystem; @@ -9,14 +10,16 @@ use League\Flysystem\FilesystemException; use League\Flysystem\UnableToCopyFile; use League\Flysystem\UnableToMoveFile; +use League\Flysystem\UnableToProvideChecksum; use League\Flysystem\UnableToRetrieveMetadata; use League\Flysystem\Visibility; use PlatformCommunity\Flysystem\BunnyCDN\BunnyCDNAdapter; use PlatformCommunity\Flysystem\BunnyCDN\BunnyCDNClient; use PlatformCommunity\Flysystem\BunnyCDN\BunnyCDNRegion; +use PlatformCommunity\Flysystem\BunnyCDN\Util; use Throwable; -class FlysystemTest extends FilesystemAdapterTestCase +class FlysystemAdapterTest extends FilesystemAdapterTestCase { public const DEMOURL = 'https://example.org.local'; @@ -215,6 +218,71 @@ public function overwriting_a_file(): void }); } + /** + * @test + */ + public function get_checksum(): void + { + $adapter = $this->adapter(); + + $adapter->write('path.txt', 'foobar', new Config()); + + $this->assertSame( + '3858f62230ac3c915f300c664312c63f', + $adapter->checksum('path.txt', new Config()) + ); + + $this->assertSame( + 'c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2', + $adapter->checksum('path.txt', new Config(['checksum_algo' => 'sha256'])) + ); + } + + public function test_checksum_throws_error_with_non_existing_file_on_default_algo(): void + { + $adapter = $this->adapter(); + + $this->expectException(UnableToProvideChecksum::class); + $adapter->checksum('path.txt', new Config(['checksum_algo' => 'sha256'])); + } + + //test_checksum_throws_error_with_empty_checksum_from_client + public function test_checksum_throws_error_with_empty_checksum_from_client(): void + { + $client = $this->createMock(BunnyCDNClient::class); + $client->expects(self::exactly(1))->method('list')->willReturnCallback( + function () { + ['file' => $file, 'dir' => $dir] = Util::splitPathIntoDirectoryAndFile('file.txt'); + $dir = Util::normalizePath($dir); + $faker = Factory::create(); + $storage_zone = $faker->word; + + return [[ + 'Guid' => $faker->uuid, + 'StorageZoneName' => $storage_zone, + 'Path' => Util::normalizePath('/'.$storage_zone.'/'.$dir.'/'), + 'ObjectName' => $file, + 'Length' => $faker->numberBetween(0, 10240), + 'LastChanged' => date('Y-m-d\TH:i:s.v'), + 'ServerId' => $faker->numberBetween(0, 10240), + 'ArrayNumber' => 0, + 'IsDirectory' => false, + 'UserId' => 'bf91bc4e-0e60-411a-b475-4416926d20f7', + 'ContentType' => '', + 'DateCreated' => date('Y-m-d\TH:i:s.v'), + 'StorageZoneId' => $faker->numberBetween(0, 102400), + 'Checksum' => null, + 'ReplicatedZones' => '', + ]]; + } + ); + + $adapter = new BunnyCDNAdapter($client); + $this->expectException(UnableToProvideChecksum::class); + $this->expectExceptionMessage('Unable to get checksum for file.txt: Checksum not available.'); + $adapter->checksum('file.txt', new Config(['checksum_algo' => 'sha256'])); + } + /** * @test */ diff --git a/tests/MockClient.php b/tests/MockClient.php index 2679fba..0c87bf0 100644 --- a/tests/MockClient.php +++ b/tests/MockClient.php @@ -39,6 +39,7 @@ public function list(string $path): array ? self::example_folder($file->path(), $this->storage_zone_name, []) : self::example_file($file->path(), $this->storage_zone_name, [ 'Length' => $file->fileSize(), + 'Checksum' => hash('sha256', $this->filesystem->read($file->path())), ]); })->toArray(); } catch (FilesystemException $exception) { diff --git a/tests/PrefixTest.php b/tests/PrefixTest.php index 3522cd7..32c1a00 100644 --- a/tests/PrefixTest.php +++ b/tests/PrefixTest.php @@ -12,7 +12,6 @@ use League\Flysystem\Visibility; use PlatformCommunity\Flysystem\BunnyCDN\BunnyCDNAdapter; use PlatformCommunity\Flysystem\BunnyCDN\BunnyCDNClient; -use PlatformCommunity\Flysystem\BunnyCDN\Util; class PrefixTest extends FilesystemAdapterTestCase { @@ -99,10 +98,6 @@ public function overwriting_a_file(): void } /** - * This seems to be a bug in flysystem's path prefixer, same with temporary URLs - * Opened https://github.com/thephpleague/flysystem/pull/1595 to fix it over there. Below is the fix for here. - * TODO Remove when merged and update lockfile - * * @test */ public function get_checksum(): void @@ -115,7 +110,15 @@ public function get_checksum(): void $adapter->write('path.txt', 'foobar', new Config()); - $this->assertSame('3858f62230ac3c915f300c664312c63f', $adapter->checksum(Util::normalizePath(self::PREFIX_PATH.'/path.txt'), new Config())); + $this->assertSame( + '3858f62230ac3c915f300c664312c63f', + $adapter->checksum('path.txt', new Config()) + ); + + $this->assertSame( + 'c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2', + $adapter->checksum('path.txt', new Config(['checksum_algo' => 'sha256'])) + ); } public function test_construct_throws_error(): void