autoaction/vbn-php-client

Pacote para geração de URLs assinadas do GCP CDN.

v2.0.0 2025-07-14 20:44 UTC

README

É necessário que o usuário que vai acessar o GCP tenha essa permissão, caso contrário o cache não poderá ser invalidado

compute.urlMaps.invalidateCache

Certifique-se que o bucket está mapeado em um Load Balancer no GCP

Consulte o Notion específico para realizar as etapas abaixo: :: Acesse o Load Balancer :: Cria um backend de Bucket :: Crie o mapeamento do backent e o bucket

Em caso de atualização da lib

:: Fazer o push dentro da branch master :: criar uma tag vxxxxx (Ex: v1.0.8)

git tag v1.0.8

:: Fazer o push da tag

git push origin v1.0.8

Documento do Client para VBN

Inspirado em DSL(Domain Specific Language) internas, para controle e solicitação fluída

Abaixo um exemplo prático de como o cliente deve se comportar

Para tests

Subir os containers

make up

Executar testes em versões PHP 5.6 e PHP 7.1

make test

Fase de configuração

<?php

namespace NAMESPACE\Libs;

use AutoAction\VBNAutoAction\Response\CollectionResponses;
use AutoAction\VBNAutoAction\VBNAutoAction;
use Config\ConfigStatic;
use Google\Cloud\Storage\StorageClient;
use Exception;
use GuzzleHttp\Psr7\Response;

class VBNHelper extends VBNAutoAction
{
    const VBN_PROD_URL = 'https://url_da_cdn';
    const GOOGLE_LOAD_BALANCE = 'nome_do_load_balance';
    const DEFAULT_BUCKET = '';
    const GOOGLE_URL_MAP_NAME = 'nome_da_url_map';
    const CDN_TO_BUCKET = [
        'url_do_cdn_1' => [
            'bucket_mapeado_1',
            'bucket_mapeado_2'
        ],
        'url_do_cdn_2' => 'bucket_mapeado_1',
    ];

    /**
    * Inicializa a configuração com as chaves e valores necessários.
    *
    * @return array
    * 
    * A função retorna um array associativo com os seguintes itens:
    * 
    * - 'cdn_key_name' (string): Nome da chave criada no balanceador de carga.
    * - 'cdn_key_value' (string): Valor da chave criada no balanceador de carga.
    * - 'google_key_file_path' (string): Caminho para o arquivo com as credenciais do Google Cloud Platform (GCP).
    * - 'google_bucket_mapped' (array): Lista de nomes de buckets mapeados no balanceador de carga.
    * - 'cdn_hostname' (string): url completa do cdn sem http/https.
    */
    private static function initConfig(): array
    {
        return [
            'cdn_key_name' => nome_da_key_criado_no_load_balance,
            'cdn_key_value' => valor_da_key_criado_no_load_balance,
            'google_key_file_path' => arquivo_com_as_credenciais_do_gcp,
            'google_bucket_mapped' => array_com_nomes_dos_bucket_mapeados_no_load_balance,
            'cdn_hostname' => parse_url(self::VBN_PROD_URL, PHP_URL_HOST),
        ];
    }

    /**
     * @param string $bucketName
     * @param string $prefix
     * @return SingleResponse
     * @throws Exception
     */
    public static function getOneSingleImage(string $bucketName, string $prefix): SingleResponse
    {
        self::init(self::initConfig());
        $imagePath = "/{$bucketName}/{$prefix}";
        $collection = self::getOneImage($imagePath);
        /*
         * FIXME: Função utilizada para pegar os metadados do arquivo e agrupar com as url's assinadas
         *  os metadados vêem do bucket no GCP, então tem um custo para fazer essas requisições
        $metadata = self::getSingleFileMetadata($imagePath, $bucketName);
        if (!empty($metadata)) {
            self::addMetadataToSingle($collection, $metadata);
        }
        */

        return $collection;
    }

    /**
     * @param string $bucketName
     * @param string $prefix
     * @return CollectionResponses
     * @throws Exception
     */
    public static function getImagesByPrefix(string $bucketName, string $prefix): CollectionResponses
    {
        self::init(self::initConfig());
        self::setBucket($bucketName);
        self::getGcpCredentials();
        if (!self::$credentials) {
            $response = new Response(200, [], []);
            return new CollectionResponses($response);
        }

        $storage = new StorageClient([
            'credentials' => self::$credentials
        ]);
        $bucket = $storage->bucket($bucketName);
        $objects = $bucket->objects([
            'prefix' => $prefix
        ]);

        try {
            $images = [];
            foreach ($objects as $object) {
                $images[] = "{$bucketName}/{$object->name()}";
            }
            $collection = self::getMultiplesImage($images);
            /*
             * FIXME: Função utilizada para pegar os metadados do arquivo e agrupar com as url's assinadas
             *  os metadados vêem do bucket no GCP, então tem um custo para fazer essas requisições
            $metadatas = self::getFileMetadataByPrefix($prefix, $bucketName);
            if (!empty($metadatas)) {
                foreach ($collection as $item) {
                    self::addMetadataToCollection($item, $metadatas);
                }
            }
            */
            return $collection;
        } catch (\Exception $e) {
            $error = [[
                'fileName' => '',
                'message' => $e->getMessage()
            ]];
            $response = new Response(200, [], json_encode($error));
            return new CollectionResponses($response);
        }
    }

    /**
     * @param array $images
     * @return CollectionResponses
     * @throws Exception
     */
    public static function getMultiplesImage(array $images): CollectionResponses
    {
        self::init(self::initConfig());
        $collection = self::getMultiplesImageSignature($images);

        /*
         * FIXME: Função utilizada para pegar os metadados do arquivo e agrupar com as url's assinadas
         *  os metadados vêem do bucket no GCP, então tem um custo para fazer essas requisições
        $metadatas = self::getMultiplesFileMetadata($images, self::$bucketName);
        if (!empty($metadatas)) {
            foreach ($collection as $item) {
                self::addMetadataToCollection($item, $metadatas);
            }
        }
        */
        return $collection;
    }

    /**
     * @param array|string $imagePaths
     * @return bool
     * @throws Exception
     * $imagePaths pode ser o nome completo do arquivo ou por prefix
     * Ex: /bucket/caminho_do_arquivo/nome_do_arquivo_1.jpg
     * ou /bucket/caminho_do_arquivo/nome_do_arquivo_*
     */
    public static function invalidateVBNCache($imagePaths): bool
    {
        self::init(self::initConfig());
        return self::invalidateCache($imagePaths);
    }

    /**
     * @param string $imagePath
     * @param string $bucketName
     * @return array
     * @throws Exception
     * $imagePaths pode ser o nome completo do arquivo ou por prefix
     * Ex: /caminho_do_arquivo/nome_do_arquivo_1.jpg
     */
    public static function getSingleFileMetadata(string $imagePath, string $bucketName): array
    {
        self::init(self::initConfig());
        self::setBucket($bucketName);
        return self::getFileMetadata($imagePath);
    }

    /**
     * @param array $imagePaths
     * @param string $bucketName
     * @return array
     * @throws Exception
     * $imagePaths pode ser o nome completo do arquivo
     * Ex: ['/caminho_do_arquivo/nome_do_arquivo_1.jpg', '/caminho_do_arquivo/nome_do_arquivo_2.jpg']
     */
    public static function getMultiplesFileMetadata(array $imagePaths,  string $bucketName): array
    {
        self::init(self::initConfig());
        self::setBucket($bucketName);
        $data = [];
        foreach ($imagePaths as $imagePath) {
            if (strpos($imagePath, $bucketName) === 0) {
                $imagePath = substr($imagePath, strlen("{$bucketName}/"));
            } elseif (strpos($imagePath, $bucketName) === 1) {
                $imagePath = substr($imagePath, strlen("/{$bucketName}/"));
            }
            $result = self::getFileMetadata($imagePath);
            $data = array_merge($data, $result);
        }
        return $data;
    }

    /**
     * @param string $imagePath
     * @param string $bucketName
     * @return array
     * @throws Exception
     * $imagePath é o nome por prefix
     * Ex: /caminho_do_arquivo/nome_do_arquivo_*
     */
    public static function getFileMetadataByPrefix(string $imagePath,  string $bucketName): array
    {
        self::init(self::initConfig());
        self::setBucket($bucketName);
        return self::getFileMetadata($imagePath, 'prefix');
    }
}