Fonte de dados: S3


1Apresentação

Amazon S3 é um espaço de armazenamento de arquivos infinito e barato. O Temma facilita a manipulação de arquivos armazenados no S3, acessando-os como qualquer outra fonte de dados.

Se você configurou corretamente os parâmetros de conexão ao S3, o Temma cria automaticamente um objeto do tipo \Temma\Datasources\S3. Por convenção, vamos supor que você nomeou essa conexão s3 no arquivo etc/temma.php (veja a documentação de configuração).

A conexão fica então disponível no controlador da seguinte forma:

$s3 = $this->s3;

Nos demais objetos gerenciados pelo componente de injeção de dependências, a conexão ao S3 é acessível da seguinte forma:

$s3 = $loader->dataSources->s3;
$s3 = $loader->dataSources['s3'];

2Instalação

Para se conectar à AWS (Amazon Web Services), o Temma precisa acessar o AWS PHP SDK. Isso pode ser feito instalando-o com o Composer, ou instalando-o manualmente.


2.1Instalação com o Composer

Para instalar o AWS PHP SDK com o Composer, basta digitar este comando a partir da raiz do projeto:

$ composer require aws/aws-sdk-php

2.2Instalação manual

Para instalar o AWS PHP SDK manualmente, baixe o arquivo aws.phar e coloque-o no diretório lib/ do projeto. Por exemplo, executando o seguinte comando:

$ wget -O lib/aws.phar https://docs.aws.amazon.com/aws-sdk-php/v3/download/aws.phar

Você também pode optar por instalar o AWS PHP SDK em nível de sistema, para não ter que reinstalá-lo em cada projeto. Para isso, basta copiar o arquivo aws.phar para um diretório que faça parte dos caminhos de inclusão, como /usr/share/php (em vez de colocá-lo no diretório lib/ do seu projeto).


3Configuração

No arquivo etc/temma.php (veja a documentação de configuração), você declara o DSN (Data Source Name) usado para se conectar ao S3.

O DSN usado para se conectar ao S3 é escrito como: s3://ACCESS_KEY:PRIVATE_KEY@REGION/BUCKET
A chave de acesso e a chave privada são fornecidas pela AWS.
A região tem o formato "us-east-1", "eu-west-3", "ca-central-1", etc.
Exemplo : s3://AKXYZ:PWD@eu-west-1/data.mydomain.com


4Armazenamento de arquivos no S3

Por padrão, os arquivos registrados pelo Temma no Amazon S3 em modo bruto têm o tipo MIME application/octet-stream, com acesso privado.

Ao registrar um arquivo, é possível especificar outro tipo MIME e/ou um direito de acesso público.

Os arquivos salvos no Amazon S3 em modo serializado sempre têm o tipo MIME application/json.


5Chamadas unificadas

5.1Acesso tipo array

// verifica a existência do arquivo
if (isset($s3['path/key1']))
    doSomething();

// lê arquivo (desserializado)
$data = $s3['path/key1'];

// grava arquivo (serializado)
$s3['path/key1'] = $value;

// apaga arquivo
unset($s3['path/key1']);

// conta arquivos
$cnt = count($s3);

5.2Métodos gerais

// verifica a existência do arquivo
if ($s3->isSet('user/1'))
    doSomething();

// apaga arquivo
$s3->remove('user/1');

// apaga vários arquivos
$s3->mRemove(['user/1', 'user/2', 'user/3']);

// apaga arquivos a partir de um prefixo
$s3->clear('user/');

// apaga todos os arquivos
$s3->flush();

5.3Gerenciamento de dados complexos serializados

// busca arquivos a partir de um prefixo
$users = $s3->search('user/');

// busca arquivos a partir de um prefixo, com recuperação dos dados
// (desserializados)
$users = $s3->search('user/', true);

// busca paginada (10 resultados a partir do 20º)
$users = $s3->search('user/', true, 20, 10);

// lê arquivo (desserializado)
$user = $s3->get('user/1');
// lê arquivo com valor padrão
$color = $s3->get('color', 'blue');
// lê arquivo, criando o arquivo se necessário
$user = $s3->get("user/$userId", function() use ($userId) {
    return $this->dao->get($userId);
});
// lê arquivo, criando o arquivo se necessário,
// com acesso público
$user = $s3->get("user/$userId", function() use ($userId) {
    return $this->dao->get($userId);
}, true);

// lê vários arquivos (desserializados)
$users = $s3->mGet(['user/1', 'user/2', 'user/3']);

// grava arquivo (serializado)
$s3->set('user/1', $userData);
// grava arquivo (serializado) com acesso público
$s3->set('user/1', $userData, true);

// grava vários arquivos (serializados)
$s3->mSet([
    'user/1' => $user1data,
    'user/2' => $user2data,
    'user/3' => $user3data,
]);
// grava vários arquivos, com acesso público
$s3->mSet([
    'user/1' => $user1data,
    'user/2' => $user2data,
], true);

5.4Gerenciamento de dados brutos

// busca arquivos a partir de um prefixo
$colors = $s3->find('color/');

// busca arquivos a partir de um prefixo, com recuperação dos dados (brutos)
$colors = $s3->find('color/', true);

// busca paginada (10 resultados a partir do 20º)
$colors = $s3->find('color/', true, 20, 10);

// lê arquivo (bruto)
$html = $s3->read('page/home');
// lê arquivo com valor padrão
$html = $s3->read('page/home',
                        '<html><body><h1>Homepage</h1><body><html>');
// lê arquivo, criando o arquivo se necessário
$html = $s3->read('page/home', function() {
    return file_get_contents('/path/to/homepage.html');
});

// lê vários arquivos (brutos)
$pages = $s3->mRead(['page/home', 'page/admin', 'page/products']);

// copia um dado para um arquivo local
$s3->copyFrom('page/home', '/path/to/newpage.html');
// copia dado para um arquivo local, com valor padrão
$s3->copyFrom('page/home', '/path/to/newpage.html', $defaultHtml);
// copia dado para um arquivo local, criando o dado se necessário
$s3->copyFrom('page/home', '/path/to/newpage.html', function() {
    return file_get_contents('/path/to/oldpage.html');
});
// copia dado para um arquivo local, criando o dado
// se necessário (com um tipo MIME específico)
$s3->copyFrom('page/home', '/path/to/newpage.html', function() {
    return file_get_contents('/path/to/oldpage.html');
}, 'text/html');
// copia dado para um arquivo local, criando o dado
// se necessário (com acesso público)
$s3->copyFrom('page/home', '/path/to/newpage.html', function() {
    return file_get_contents('/path/to/oldpage.html');
}, true);
// copia dado para um arquivo local, criando o dado
// se necessário (com um tipo MIME específico e acesso público)
$s3->copyFrom('page/home', '/path/to/newpage.html', function() {
    return file_get_contents('/path/to/oldpage.html');
}, [
    'public'   => true,
    'mimetype' => 'text/html',
]);

// grava arquivo (bruto)
$s3->write('user/1', $userData);
// grava arquivo (bruto) com um tipo MIME específico
$s3->write('user/1', $userData, 'application/pdf');
// grava arquivo (bruto) com acesso público
$s3->write('user/1', $userData, true);
// grava arquivo (bruto) com um tipo MIME específico
// e acesso público
$s3->write('user/1', $userData, [
    'public'   => true,
    'mimetype' => 'application/pdf',
]);

// grava vários arquivos (brutos)
$s3->mWrite([
    'color/blue'  => '#0000ff',
    'color/red'   => '#ff0000',
    'color/green' => '#00ff00',
]);
// grava vários arquivos com um tipo MIME específico
$s3->mWrite([
    'color/blue'  => '#0000ff',
    'color/red'   => '#ff0000',
], 'text/plain');
// grava vários arquivos com acesso público
$s3->mWrite([
    'color/blue'  => '#0000ff',
    'color/red'   => '#ff0000',
], true);
// grava vários arquivos com um tipo MIME específico
// e acesso público
$s3->mWrite([
    'color/blue'  => '#0000ff',
    'color/red'   => '#ff0000',
], [
    'public'   => true,
    'mimetype' => 'text/plain',
]);

// grava arquivo (bruto) a partir de um arquivo local
$s3->copyTo('page/home', '/path/to/homepage.html');
// grava arquivo (bruto) a partir de um arquivo local, com um tipo MIME específico
$s3->copyTo('page/home', '/path/to/homepage.html', 'text/html');
// grava arquivo (bruto) a partir de um arquivo local, com acesso público
$s3->copyTo('page/home', '/path/to/homepage.html', true);
// grava arquivo (bruto) a partir de um arquivo local, com um tipo MIME específico
// e acesso público
$s3->copyTo('page/home', '/path/to/homepage.html', [
    'public'   => true,
    'mimetype' => 'text/html',
]);

// grava vários arquivos (brutos) a partir de arquivos locais
$s3->mCopyTo([
    'page/home'     => '/path/to/homepage.html',
    'page/admin'    => '/path/to/admin.html',
    'page/products' => '/path/to/products.html',
]);
// grava vários arquivos a partir de arquivos locais com tipo MIME específico
$s3->mCopyTo([
    'page/home'  => '/path/to/homepage.html',
    'page/admin' => '/path/to/admin.html',
], 'text/html');
// grava vários arquivos a partir de arquivos locais com acesso público
$s3->mCopyTo([
    'page/home'  => '/path/to/homepage.html',
    'page/admin' => '/path/to/admin.html',
], true);
// grava vários arquivos a partir de arquivos locais, com tipo MIME específico
// e acesso público
$s3->mCopyTo([
    'page/home'  => '/path/to/homepage.html',
    'page/admin' => '/path/to/admin.html',
], [
    'public'   => true,
    'mimetype' => 'text/html',
]);

6Chamadas específicas

6.1getUrl()

getUrl(string $s3Path) : string

Basicamente, os arquivos armazenados no S3 com acesso privado não são acessíveis a usuários que não possuam uma conta AWS com direitos de acesso ao bucket ou ao próprio arquivo.

No entanto, é possível criar URLs temporárias, que permitem acessar os arquivos por um período determinado. O método getUrl() pode ser usado para criar essas URLs "pré-assinadas", que são válidas por 20 minutos.

Essas URLs são úteis para oferecer acesso a arquivos apenas a usuários autenticados no site.

Exemplo:

// obtém a URL temporária
$url = $s3->getUrl('documents/report.pdf');

// redireciona para essa URL
$this->_redirect($url);