Giter Club home page Giter Club logo

bunnynet-php's Introduction


Bunny CDN Logo

BunnyNet API client for PHP

Current bundle version Packagist Total Downloads PHP version requirement PHP-FIG PSR-18 Code style Mess detector Static analysis Unit tests Security

Bunny.net is content delivery platform that truly hops: providing CDN, edge storage, video streaming, image optimizers and much more!

Note: This is a non-official library for the bunny.net API.

🧰 Install

composer require toshy/bunnynet-php:^4.0

📜 Documentation

The documentation is available at https://toshy.github.io/BunnyNet-PHP.

🛠️ Contribute

Features and bugfixes should be based on the master branch.

Prerequisites

Install dependencies

task composer:install 

Enable GrumPHP

task grum:init

Note: Checks for phpcs, phpstan, phpmd and phpunit are executed when committing. You can also run these checks with task contribute.

❕ Licence

This repository comes with a MIT license.

bunnynet-php's People

Contributors

asecu-cloud avatar dependabot[bot] avatar hcaz avatar jeffersonsimaogoncalves avatar sopamo avatar thisispiers avatar toshy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

bunnynet-php's Issues

[Feature]: Stream API Upload Thumbnail

Description

Had a chat with Bunny support about uploading a video thumbnail, and it turns out they have an API for that, it's not in the Bunny API documentation yet. Here it is:

curl --request POST \ --url https://video.bunnycdn.com/library/id/videos/id/thumbnail \ --header 'AccessKey: key' \ --header 'Content-Type: image/png' \ --data-binary @download.png

Example

No response

[Feature]: Pull Zone - Pull Zone and Edge Rule updates

Description

The following endpoints have some additional updates to query and/or body parameters:

  • List Pull Zones
    • query parameters (new)
      • search
  • Add Pull Zone
    • body parameters (new)
      • CacheControlPublicMaxAgeOverride
      • UseBackgroundUpdate
      • MagicContainersAppId
      • DisableLetsEncrypt
      • EnableBunnyImageAi
      • BunnyAiImageBlueprints
      • PreloadingScreenEnabled
      • PreloadingScreenCode
      • PreloadingScreenLogoUrl
      • PreloadingScreenTheme
      • PreloadingScreenCodeEnabled
      • PreloadingScreenDelay
      • RoutingFilters
    • body parameters (docs)
      • LogForwardingProtocol
      • OptimizerWatermarkPosition
      • OriginType
      • LogFormat
      • LogForwardingFormat
      • ShieldDDosProtectionType
  • Update Pull Zone
    • See "Add Pull Zone" above.
  • Add/Update Edge Rule
    • body parameters (docs)
      • ActionType
      • Triggers > Type

Example

No response

Standard Storage Request

Hello,

I'm not having any problems with Edge, but unfortunately, I can't upload files to a standard server. Is it possible to upload files to standard storage?

Thank you

[Feature]: Search

Description

  1. Add the following endpoints for Search (updated at 05-04-2023):

  2. Add corresponding documentation.


Note: If anybody has any example usage(s) for this endpoint, or can give an indication on where this one is used, that would be very much appreciated 🙂

Support PSR-7 and PSR-18

Instead of being locked to using symfony/http-client, implementing guzzlehttp/psr7 and psr/http-client would give more freedom by supplying the http client yourself.

[Feature]: Stream API - Add `OEmbed` endpoint

Description

  1. Add the following endpoints for OEmbed

  2. Add corresponding documentation.


I did not know what "oEmbed" was or how it can be used, support team gave me the following answer:

This endpoint is used to return metadata about the video for services that support or use oEmbed, like embed.ly. You need to pass a URL query string as seen in the documents.
Example Video: https://iframe.mediadelivery.net/embed/182595/8a800e53-c949-46d0-8818-af566f032ec1

Example

Example cURL:

request

curl --request GET \
     --url 'https://video.bunnycdn.com/OEmbed?url=https%3A%2F%2Fiframe.mediadelivery.net%2Fembed%2F182595%2F8a800e53-c949-46d0-8818-af566f032ec1' \
     --header 'accept: application/json'

response

{
  "version": "1.0",
  "title": "鶴島の魅力を紹介!(Tsurushima no miryoku o shōkai!)",
  "type": "video",
  "thumbnail_url": "https://vz-9d706929-bc7.b-cdn.net/8a800e53-c949-46d0-8818-af566f032ec1/thumbnail.jpg",
  "width": 1920,
  "height": 1080,
  "html": "<iframe src=\"https://iframe.mediadelivery.net/embed/182595/8a800e53-c949-46d0-8818-af566f032ec1?autoplay=true\" loading=\"lazy\" width=\"1920\" height=\"1080\" style=\"border: none;\" allow=\"fullscreen; accelerometer; gyroscope; autoplay; encrypted-media; picture-in-picture;\"></iframe>",
  "provider_name": "bunny.net",
  "provider_url": "https://bunny.net/"
}

Refactoring endpoints into subcategories

Problem

Initially BaseRequest class was made to include all endpoints for the "basic" API endpoints. As most of the endpoints are neatly divided into subcategories, e.g. Countries, Pull Zone, Purge, etc., the problem arises that some functionality like purging is both available as a subcategory Purge, as well as an endpoint for the Pull Zone category /purgeCache, which could lead to confusion as it's not clear from the call directly, $baseRequest->purgeCache(), which "purge" we are actually doing.

Propose

Option 1

In order to clear things up, either the methods should be renamed. Maybe prefixing by the subcategory?

// old
$baseRequest->purgeCache();
// new
$baseRequest->pullZonePurgeCache();

This could work, but if we want to be consistent, for some subcategories this would make some not really nice looking method names

// old
$baseRequest->purgeUrl();
// new
$baseRequest->purgePurgeUrl();

Option 2

Maybe creating models for each subcategory would make things clearer.

$baseRequest->getUser()->getDetails();
$baseRequest->getUser()->updateDetails();
$baseRequest->getUser()->resetApiKey();
$baseRequest->getUser()->closeTheAccount();
$baseRequest->getUser()->getDpaDetails();

Option 3

Any other suggestions or ideas on how to improve this are welcome.

[Feature]: Stream API - Add `Repackage Video` endpoint

Description

  1. Add the following endpoint for Repackage Video

  2. Add corresponding documentation.

Example

No response


Note:

Was unsure what this endpoint does, so asked the support team which gave me the following answer:

Basically, repackaging videos means that you can take videos not using DRM and transcode them to be ready for Enterprise DRM without re-uploading the videos.

So it's a specific endpoint for Enterprise DRM.

[Feature]: AuthPublic

Description

  1. Add the following endpoints for AuthPublic (updated at 05-04-2023):

  2. Add corresponding documentation.


Note: I'm not sure yet where/how these endpoints are actually used, but think it's related to the new dashboard: https://dash.bunny.net. If anybody has any example usages for these endpoints, or can give an indication on where these are used, that would be very much appreciated 🙂

[Feature]: Upload video from external folder like FTP

Description

I notice that when we want to upload a video the parameter require is path to file(local file).
I try to duplicate uploadVideo function and remove the function to check the file locally and just return the streamData (the video) and it work.

here is the code
streamAPI.php

public function uploadVideoFTP(
        int $libraryId,
        string $videoId,
        string $ftpStream,
        array $query = [],
    ): BunnyClientResponseInterface {
        $endpoint = new UploadVideoFTP();

        ParameterValidator::validate($query, $endpoint->getQuery());

        return $this->client->request(
            endpoint: $endpoint,
            parameters: [$libraryId, $videoId],
            query: $query,
            body: $ftpStream,
        );
    }

and this code is duplicating uploadVideo.php

public function uploadVideoFTP(
        int $libraryId,
        string $videoId,
        string $ftpStream,
        array $query = [],
    ): BunnyClientResponseInterface {
        $endpoint = new UploadVideoFTP();

        ParameterValidator::validate($query, $endpoint->getQuery());

        return $this->client->request(
            endpoint: $endpoint,
            parameters: [$libraryId, $videoId],
            query: $query,
            body: $ftpStream,
        );
    }

but i don't know what is the best way to make this code better, so i create this issues so you can take a look.
thanks

Example

No response

[Feature]: Add discussions to this repo

Description

I have some questions that are neither bug reports nor feature requests, would you consider enabling Discussions?

Example

Is there a way to download the metadata of all the objects in a storageZone? Obviously, a recursive function that calls listFiles() and/or listContents() would work, but generate many API calls if there are a lot of directories.

I have a million objects, each object has 0 or more photos and the photos and metadata for each object is in a directory keyed by the object id. S3 doesn't really have directories, so this approach is fine, but I'm wondering if I need to restructure if we migrate to Bunny.

            $list = $edgeStorageApi->listFiles(
                storageZoneName: $storageZoneName,
                path: '/'
            );

            foreach ($list->getContents() as $fileInfo) {
                $subList = $edgeStorageApi->listFiles(
                    $storageZoneName,
                    path: $fileInfo['ObjectName']
                );

               // @todo: add recursive call

            }

Convert enums to models

Current situation

Currently enums used for the several endpoints use arrays containing several properties:

[
  'method' => '',
  'path' => '',
  'headers' => [],
  'query' => [],
  'body' => [],
];

Desired situation

Coming to like the usage of models more and more, I think converting the current enums would be a nice addition to write more maintainable code.

With that the suggestion to create an abstract/generic class containing the properties the enums currently have:

<?php

declare(strict_types=1);

namespace ToshY\BunnyNet\Enum;

class AbstractEndpoint
{
    public function __construct(
        private readonly string $method,
        private readonly string $path,
        private readonly array $headers,
        private readonly array $query,
        private readonly array $body,
    ) {
    }
    
    public function getMethod(): string
    {
        return $this->method;
    }
    
    public function getPath(): string
    {
        return $this->path;
    }
    
    public function getHeaders(): array
    {
        return $this->headers;
    }
    
    public function getQuery(): array
    {
        return $this->query;
    }
    
    public function getBody(): array
    {
        return $this->body;
    }
}

Extra

This might all be combined with migrating to PHP 8.x, meaning that new features will only be added in PHP 8.x compatible branch and releases.

Related
#38

[Feature]: Fetch thumbnails with GetCollection

Description

I'd like to fetch the thumbnail of a video I uploaded, and the only way I can find it through the GetCollection endpoint.
If we add a query parameter ?includeThumbnails=true to the path, the response includes the thumbnail links.

I don't think the current implementation allows adding custom query parameters, so maybe an additional EndpointInterface alongside GetCollection is needed?

Example

class GetCollection implements EndpointInterface
{
    public function getMethod(): Method
    {
        return Method::GET;
    }

    public function getPath(): string
    {
        return 'library/%d/collections/%s**?includeThumbnails=true**';
    }

    public function getHeaders(): array
    {
        return [
            Header::ACCEPT_JSON,
        ];
    }
}

Create response model for request

Current situation

Currently the response from a request is an array with the following structure:

[
    'content' => $responseContent,
    'headers' => $response->getHeaders(self::THROW_CLIENT_EXCEPTIONS),
    'status' => [
        'code' => $response->getStatusCode(),
        'info' => $response->getInfo(),
    ],
]

Desired situation

Creating a response model containing the above mentioned (typed) properties, makes it easier for both developer as well as IDE to deduce the response information available.

Extra

Seems like a good way to start using models more often, for example the current enums could be converted as well. Creating a abstract or generic class containing properties method, path, headers, query, body and extend the new enum models from this.

Error in deleteVideo method

Is:

return $this->request(
            $endpoint['method'],
            [$libraryId, $videoId]
        );

Should be:

return $this->request(
            $endpoint,
            [$libraryId, $videoId]
        );

How does the file download work?

Hello,

Thank you for your repo.
Direct friend downloading does not start. with "var_dump", the codes of the file are displayed. How can I start the direct download? Can you help with this too?

$bunnyEdgeStorage->downloadFile('my-storage-zone-1', 'css', 'new-custom.css');

Thank you

[Bug]: can't use Symfony HttpClient

Package version(s) affected

4.2.1

Description

I'd like to use the Symfony Client, which implement the psr interface (second on this list: https://packagist.org/providers/psr/http-client-implementation)

How to reproduce

But when I try to initialize the library

       $bunnyClient = new BunnyClient(
            client: (new HttpClient()) // or inject the default http client, same problem
        );

I get ToshY\BunnyNet\Client\BunnyClient::__construct(): Argument #1 ($client) must be of type Psr\Http\Client\ClientInterface, Symfony\Component\HttpClient\TraceableHttpClient given

Possible Solution

I think the issue is the type, Symfony uses cache contracts.

use Symfony\Contracts\HttpClient\HttpClientInterface;

Additional Context

I was able to get it to work by installing

composer require php-http/discovery

and finding the implementation

        $httpClient =  Psr18ClientDiscovery::find();
// Create a BunnyClient using any HTTP client implementing "Psr\Http\Client\ClientInterface".
        $bunnyClient = new BunnyClient(
            client: $httpClient
        );

I'm sure I'm just confused about the interfaces, perhaps you could add something to the documentation as to how to use your own http client.

Tx.

[Feature]: DNS - List DNS Zones and Add/Update DNS record query/body parameter updates

Description

The following endpoints have some additional updates to query and/or body parameters:

Note that the documentation for these above DNS endpoints have been updated for body parameters Type, MonitorType and SmartRoutingType. Update the documentation accordingly.

Example

No response

VideoStreamRequest->createVideo fails to create new video

When calling the createVideo endpoint as part of the VideoStreamRequest it throws an error due to the wrong content-type header being set. According to the docs the header should be 'Content-Type' => 'application/*+json'. This is available within the Header enum and just needs changing in the VideoEndpoint.php set of constants.

  "content" => array:4 [▼
    "type" => "https://tools.ietf.org/html/rfc7231#section-6.5.13"
    "title" => "Unsupported Media Type"
    "status" => 415
    "traceId" => "00-e85c6c5a7f5df7187fa7438f6282af68-8fdf8a6359a16646-00"
  ]

Timeout issue

Hello, i am getting this error during the upload:

PHP Fatal error: Uncaught Symfony\Component\HttpClient\Exception\TransportException: Idle timeout reached for "https://video.bunnycdn.com/library/.........

I am looking for a way to set the timeout but i can't find it

Create Collection wrong endpoint

Needed to go deep to find it since I got no explanations from errors 🗡️

"exception":"[object] (ArgumentCountError(code: 0): 3 arguments are required, 2

Get this error on createCollection($libraryId, $body) where it calls for CollectionEndpoint::CREATE_COLLECTION

That uses: 'path' => 'library/%d/collections/%s', however the api doesn't use second parameter so you should just remove /%s.

Here is a fix if you want to merge it: #49

@ToshY cheers

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.