Repository: appwrite/appwrite
File: app/controllers/api/storage.php (PHP)

Code before:
                System::getEnv('_APP_OPENSSL_KEY_V' . $file->getAttribute('openSSLVersion')),
                0,
                \hex2bin($file->getAttribute('openSSLIV')),
                \hex2bin($file->getAttribute('openSSLTag'))
            );
        }

        $decryptionTime = \microtime(true) - $startTime - $downloadTime;

        switch ($algorithm) {
            case Compression::ZSTD:
                $compressor = new Zstd();
                $source = $compressor->decompress($source);
                break;
            case Compression::GZIP:
                $compressor = new GZIP();
                $source = $compressor->decompress($source);
                break;
        }

        $decompressionTime = \microtime(true) - $startTime - $downloadTime - $decryptionTime;

        if (empty($source)) {
            $source = $deviceForFiles->read($path);
        }

        try {
            $image = new Image($source);
        } catch (ImagickException $e) {
            throw new Exception(Exception::STORAGE_FILE_TYPE_UNSUPPORTED, $e->getMessage());
        }

        $image->crop((int) $width, (int) $height, $gravity);

        if (!empty($opacity) || $opacity === 0) {
            $image->setOpacity($opacity);
        }

        if (!empty($background)) {
            $image->setBackground('#' . $background);
        }

        if (!empty($borderWidth)) {
            $image->setBorder($borderWidth, '#' . $borderColor);
        }

        if (!empty($borderRadius)) {
            $image->setBorderRadius($borderRadius);
        }

        if (!empty($rotation)) {

Review comment (bug):
A bit scared to do storage API change due to sites screenshot bug.
I would guess this scenario can never happen, otherwise we would have already fixed it here - it must be sites specific problem. So I would guess sites just dont create file document properly.

Please look into Builds.php (worker), and see how screenshot document is created. My guess would be, that there we dont set 'source' parameter. Compare that to `createFile` endpoint, here in storage.php, to see what expected value is. With that knowledge you should be able to have fix be done in Builds.php worker, and so we can then remove this fix in getFilePreview.

^ If this works, I would prefer that. if it doesn't, let's keep this fix, and I will ask other leads for review, to make sure this is safe to do.

Code after:
                System::getEnv('_APP_OPENSSL_KEY_V' . $file->getAttribute('openSSLVersion')),
                0,
                \hex2bin($file->getAttribute('openSSLIV')),
                \hex2bin($file->getAttribute('openSSLTag'))
            );
        }

        $decryptionTime = \microtime(true) - $startTime - $downloadTime;

        switch ($algorithm) {
            case Compression::ZSTD:
                $compressor = new Zstd();
                $source = $compressor->decompress($source);
                break;
            case Compression::GZIP:
                $compressor = new GZIP();
                $source = $compressor->decompress($source);
                break;
        }

        $decompressionTime = \microtime(true) - $startTime - $downloadTime - $decryptionTime;

        try {
            $image = new Image($source);
        } catch (ImagickException $e) {
            throw new Exception(Exception::STORAGE_FILE_TYPE_UNSUPPORTED, $e->getMessage());
        }

        $image->crop((int) $width, (int) $height, $gravity);

        if (!empty($opacity) || $opacity === 0) {
            $image->setOpacity($opacity);
        }

        if (!empty($background)) {
            $image->setBackground('#' . $background);
        }

        if (!empty($borderWidth)) {
            $image->setBorder($borderWidth, '#' . $borderColor);
        }

        if (!empty($borderRadius)) {
            $image->setBorderRadius($borderRadius);
        }

        if (!empty($rotation)) {
            $image->setRotation(($rotation + 360) % 360);
        }

        $data = $image->output($output, $quality);