Você está na página 1de 14

O projeto começa pela criação da tabela que no banco de dados 0_transfer que abrigará as

fotos identificadas. Para criar a tabela "sa_pedido_evento_foto" com as colunas


especificadas no banco de dados "0_transfer", será usada a seguinte sintaxe em SQL:

CREATE TABLE 0_transfer.sa_pedido_evento_foto (


id_pedido_evento_foto INT NOT NULL AUTO_INCREMENT,
id_pedido_evento INT,
id_pedido INT,
id_evento INT,
nr_peito INT,
id_usuario INT,
fl_balcao ENUM('B','S'),
ds_email VARCHAR(255),
ds_nomecompleto VARCHAR(255),
ds_url_imagem TEXT,
id_usuario_up_foto INT,
dt_identificacao DATETIME,
PRIMARY KEY (id_pedido_evento_foto)
);

Esta sintaxe cria uma tabela com as seguintes colunas:

● id_pedido_evento_foto: chave primária da tabela, criada com um número


inteiro que é incrementado automaticamente (AUTO_INCREMENT).
● id_pedido_evento: número inteiro que identifica a inscrição do atleta.
● id_pedido: número inteiro que identifica o pedido.
● id_evento: número inteiro que identifica o evento.
● nr_peito: número inteiro que identifica com o número do peito.
● id_usuario: número inteiro que identifica o usuário a que pertence a foto.
● fl_balcao: caractere (char) que indica se é um balcão (B) ou SITE (S).
● ds_email: string com o e-mail do usuário.
● ds_nomecompleto: string com o nome completo do usuário.
● ds_url_imagem: string com a URL da imagem.
● id_usuario_up_foto: número inteiro que identifica o usuário que fez o upload
da foto.
● dt_identificacao: data e hora em que a foto foi identificada.

Depois da tabela sa_pedido_evento_foto criada o segundo passo foi iniciar a


integração do Controller PedidoeventofotoController.
<?php
class PedidoeventofotoController extends Zend_Controller_Action
{
public function init()
{
$sessao = new Zend_Session_Namespace('autenticacao');
if ($sessao->username == null) {
$this->_helper->redirector->gotoSimple("index", "login");
}

//liberar memória p/ relatório


ini_set('max_execution_time', 0);
ini_set('memory_limit', '6400M');
ini_set('upload_max_filesize', '100M');

$this->view->menu();
} //init

public function indexAction()


{
$EventosModel = new EventoModel();
$this->view->listevento = $EventosModel->getComboEventosCasa();
}

Esse código é parte de um sistema web desenvolvido em PHP, usando o framework


Zend. Ele é responsável por exibir uma página web com um formulário para upload de
arquivos relacionados a eventos.

A função indexAction() é responsável por chamar a função getComboEventosCasa()


do modelo EventoModel(), que retorna um array com os eventos disponíveis para
seleção no formulário. Esses eventos são exibidos em um menu suspenso (select) do
HTML usando a biblioteca Bootstrap-Select.

<form name="id_evento" method="POST"


action="<?=$this->url(array('controller' => 'Pedidoeventofoto',
'action' => 'upload'))?>" enctype="multipart/form-data"

style="width:70%;height:350px;display:flex;flex-direction:column;justif
y-content: space-evenly;">
<div class="form-group">
<label for="imagem_principal"
class="control-label"><strong>Selecione o Evento das
Fotos</strong></label>
<select name="evento" class="form-control selectpicker"
data-live-search="true" id="eventos" required>
<?php if(is_array($this->listevento) &&
count($this->listevento) > 0):?>
<?php foreach($this->listevento as $key => $evento) :?>
<option value="<?=$key?>" data-content="<img
class='grayscale email' width='70px;'
src='https://media.ativo.com/upload/evento/<?=$key?>/img_banner_evento.
jpg'</img> <?=$evento?>"> <?=$evento?> </option>
<?php endforeach;?>
<?php endif?>
</select>

</div>

<div class="form-group">
<label for="file"><strong>Selecione um
arquivo:</strong></label>
<input type="file" id="file" name="file"
accept=".zip" required>
</div>

<input type="submit" value="Uploud" class="btn btn-success"


style="font-size: 11pt;margin-top:20px;width:15%"/>
</form>
</div>

O formulário contém dois campos: um menu suspenso para selecionar o evento ao


qual o arquivo pertence e um campo para selecionar um arquivo a ser enviado
(somente arquivos .zip são permitidos). Quando o formulário é enviado, ele chama a
ação upload do controlador Pedidoeventofoto.

Na exibição do menu suspenso, é possível observar que cada opção possui uma
imagem do banner do evento e uma descrição do evento. Os dados do evento são
obtidos a partir da função getComboEventosCasa(), que consulta o banco de dados
para buscar os eventos. É possível observar que há um código hardcoded para dois
eventos específicos no final da função, que provavelmente são inseridos manualmente
para adicionar opções ao menu suspenso.
Por fim, a página faz uso das bibliotecas Bootstrap e JQuery, além da biblioteca
Bootstrap-Select, para melhorar a aparência e a funcionalidade da página.

Para enviar um arquivo das imagens que deve está zipado e contendo em média 2GB
de dados é preciso aumentar o valor da directiva "upload_max_filesize" para um valor
igual ou superior a 5 GB para que se tenha um espaço para o processamento do uploud
do arquivo..

A configuração padrão geralmente é 2 MB ou 8 MB, dependendo da configuração do


servidor. Para alterá-la, é preciso editar o arquivo php.ini e modificar o valor para um
valor maior.

Para enviar um arquivo de 5GB, é necessário definir o valor para 5G ou mais. Por
exemplo, para definir o valor como 5GB, pode-se usar a seguinte diretiva no arquivo
php.ini:

upload_max_filesize = 5G

É importante salientar que, além de aumentar o valor de "upload_max_filesize",


também é necessário ajustar o valor da diretiva "post_max_size" para um valor igual
ou superior a 5 GB. Essa diretiva define o tamanho máximo de toda a solicitação
HTTP, incluindo todos os dados enviados via POST, não apenas o arquivo de upload.

É possível ajustar o "upload_max_filesize" e o "post_max_size" diretamente via linha


de comando no terminal usando o comando "sed" para editar o arquivo php.ini.

Primeiro, verificando onde o arquivo php.ini está localizado executando o seguinte


comando:

php --ini

Depois de localizar o arquivo php.ini, é possível editar o arquivo usando o comando


"sed". Por exemplo, se o arquivo php.ini estiver localizado em
/etc/php/7.0/apache2/php.ini, o comando a ser executado é o seguinte para realizar as
alterações nas configurações de "upload_max_filesize" e "post_max_size" para 5 GB
sudo sed -i 's/^upload_max_filesize.*/upload_max_filesize = 5G/'
/etc/php/7.0/apache2/php.ini
sudo sed -i 's/^post_max_size.*/post_max_size = 5G/'
/etc/php/7.0/apache2/php.ini
Para salvar as alterações é preciso reiniciar o servidor Apache:

sudo service apache2 restart

Depois de reiniciar o servidor, o limite de tamanho de upload de arquivos deve estar


configurado para 5 GB.

Tudo estando certo com a configuração do servidor para uploads grandes quando o
formulário é for enviado, ele chamará a uploadAction() do controlador
Pedidoeventofoto.

public function uploadAction()


{
$fotos = new Zend_Session_Namespace('fotos');
$params = $this->_request->getParams();
$fotos->id_evento = $params['evento'];
$pastaArquivo =
"adm/evento/atletas/fotos/".$fotos->id_evento."/";

if ($_FILES['file']['size'] > 0)
{
$zip = new ZipArchive;
if ($zip->open($_FILES['file']['tmp_name']) === TRUE)
{
$extractPath = '/tmp/extracted';

// remove todos os arquivos no diretório temporário


array_map('unlink', glob("$extractPath/*"));
rmdir($extractPath);

if (!file_exists($extractPath))
{
mkdir($extractPath);
}

$zip->extractTo($extractPath);
$zip->close();
$pedidoeventofoto = new PedidoeventofotoModel();
$fotos->imageUrls =
$pedidoeventofoto->uploud($extractPath,$pastaArquivo);
$this->_helper->redirector->gotoSimple("identifica",
"pedidoeventofoto");
} else
{
echo 'Erro ao descompactar arquivo';
exit();
}

} else
{
echo "Falha ao salvar o arquivo no S3<br>"; exit;
}
echo "URL final: ".$params['url']."<br>";
exit;
}

A função uploadAction() começa criando uma nova sessão do Zend Framework com o
nome "fotos". Em seguida, ela obtém os parâmetros da requisição e define a variável
$pastaArquivo com o caminho para a pasta onde as imagens serão armazenadas.
Depois, a função verifica se o arquivo enviado pelo usuário tem tamanho maior do
que zero. Se sim, ela cria um novo objeto ZipArchive e tenta abrir o arquivo ZIP
enviado pelo usuário. Se o arquivo for aberto com sucesso, a função cria uma pasta
temporária para extrair os arquivos ZIP e armazená-los nessa pasta. Em seguida, ela
instancia um objeto PedidoeventofotoModel e chama a função uploud() passando o
caminho da pasta temporária e o caminho para a pasta onde as imagens devem ser
armazenadas. O resultado da função uploud() é armazenado na variável
$fotos->imageUrls. Por fim, a função redireciona o usuário para a página "identifica"
do controlador "pedidoeventofoto".

Caso o arquivo ZIP enviado pelo usuário não possa ser aberto, a função exibe uma
mensagem de erro e termina a execução. Caso o arquivo tenha tamanho zero, a função
exibe uma mensagem de erro e termina a execução.

public function uploud($extractPath,$pastaArquivo)


{
$s3 = new S3Client($this->args());
$bucketName = 'media.ativo.com';
// Localiza as imagens na pasta descompactada e faz o upload
para o S3
$imageUrls = [];
if ($handle = opendir($extractPath))
{
while (false !== ($entry = readdir($handle)))
{
if ($entry != "." && $entry != "..")
{
$filePath = $extractPath . '/' . $entry;

// verificar se não é diretório


if (!is_dir($filePath))
{
$result = $s3->upload($bucketName,
$pastaArquivo . $entry, fopen($filePath, 'rb'), 'public-read');
$imageUrl = $result->get('ObjectURL');
array_push($imageUrls, $imageUrl);
}
}
}
closedir($handle);
}

return $imageUrls;

A função uploud() recebe como parâmetros o caminho da pasta temporária criada pela
função uploadAction() e o caminho para a pasta onde as imagens devem ser
armazenadas. Ela cria um novo objeto S3Client para interagir com o serviço de
armazenamento em nuvem da Amazon. Em seguida, ela itera sobre todos os arquivos
da pasta temporária, ignorando os subdiretórios. Para cada arquivo, a função faz o
upload do arquivo para o serviço S3, utilizando o caminho para a pasta onde as
imagens devem ser armazenadas como prefixo para o nome do arquivo no S3. A
função também define o nível de acesso do arquivo como "public-read", o que
significa que qualquer pessoa pode acessar o arquivo por meio de sua URL. A função
armazenar a URL do arquivo recém-carregado em uma matriz $imageUrls. Por fim, a
função retorna a matriz $imageUrls.
Em resumo, esse código implementa uma funcionalidade de upload de imagens para o
serviço de armazenamento em nuvem da Amazon S3. Ele recebe um arquivo ZIP
contendo várias imagens, extrai as imagens para uma pasta temporária, faz o upload
das imagens para o S3 e armazena as URLs dos arquivos no S3 em uma matriz. O
código usa as bibliotecas Zend Framework e AWS SDK for PHP para realizar essas
tarefas.

Se tudo ocorrer como deve ser, o usuário é redirecionado para a action identifica do
controller pedidoeventofoto usando o helper redirector. Isso significa que, após o
upload das imagens e o processamento das mesmas, o usuário será redirecionado para
a página correspondente.

public function identificaAction()


{
$fotos = new Zend_Session_Namespace('fotos');

$urlsNrPeito = array();
foreach($fotos->imageUrls as $url)
{
$pedidoeventofoto = new PedidoeventofotoModel();
$urlsNrPeito[$url] =
$pedidoeventofoto->reconhecerImagem($url);
}
$fotos->urlsNrPeito = $urlsNrPeito;
$this->_helper->redirector->gotoSimple("save",
"pedidoeventofoto");
}

A função identificaAction() é responsável por identificar os números de peito


presentes nas imagens enviadas na ação anterior uploadAction().

Primeiro, é criado um objeto Zend_Session_Namespace para obter o valor da sessão


que contém as URLs das imagens. Em seguida, um loop é criado para percorrer cada
URL e chamar a função reconhecerImagem($imageUrl), que é responsável por
reconhecer os números de peito na imagem, utilizando a API Rekognition da Amazon.

public function reconhecerImagem($imageUrl)


{
//Cria o Objeto Rekognition Cliete Amazon
$client = new RekognitionClient($this->args());

// Define os parâmetros para a detecção de texto na imagem


$params = [
'Image' => ['Bytes' =>
file_get_contents($imageUrl)],
'Filters' => ['Word' => ['BoundingBox', 'Confidence',
'Text']],
'DetectText' => true,
'MinConfidence' => 80,
];

// Chama a função detectText() do Amazon Rekognition para


detectar o texto na imagem
$result = $client->detectText($params);
$nrs_peito = array();

// coloca os números encontrados na imagem dentro de uma array


foreach ($result['TextDetections'] as $text)
{
if (is_numeric($text['DetectedText']))
{
array_push($nrs_peito,$text['DetectedText']);
}
}

return $nrs_peito;
}

O resultado de cada imagem é armazenado em um array associativo que tem a URL


da imagem como chave e a array com os números de peito como valor. O objeto da
sessão é atualizado com esse array de URLs e números de peito, e o usuário é
redirecionado para a ação saveAction() para que as informações sejam salvas.

Portanto, o resultado final do processo é um array associativo com as URLs das


imagens como chaves e uma array de números de peito reconhecidos como valores.

public function saveAction()


{
$fotos = new Zend_Session_Namespace('fotos');
$sessao = new Zend_Session_Namespace('autenticacao');
$pedidoeventofoto = new PedidoeventofotoModel();
foreach($fotos->urlsNrPeito as $key => $dados)
{
foreach($dados as $dado)
{
$array = array(
'id_pedido_evento' => 0,
'id_pedido' => 0,
'id_evento' => $fotos->id_evento,
'nr_peito' => $dado,
'fl_balcao' => 'S',
'ds_email' => 'default',
'ds_nomecompleto' => 'default',
'ds_url_imagem' => $key,
'id_usuario_up_foto' => $sessao->id_usuario,
'dt_identificacao' => date('Y-m-d H:i:s')
);
$pedidoeventofoto->insert($array);
}
}

$this->_helper->redirector->gotoSimple("save", "update");
}

Essa é a saveAction do controlador PedidoeventofotoController. Ela recebe as


informações identificadas na imagem em identificaAction e salva no banco de dados
usando o modelo PedidoeventofotoModel. Basicamente, essa ação faz o seguinte:
● Cria um objeto de sessão chamado fotos e recupera as informações de
urlsNrPeito que foram identificadas na ação anterior.
● Cria um objeto de sessão chamado autenticacao para recuperar o ID do usuário
que fez o upload da imagem.
● Itera sobre cada uma das URLs identificadas e, em seguida, itera sobre cada um
dos números de peito detectados nessa URL.
● Cria um array com as informações necessárias do pedido de evento e salva no
banco de dados usando o método insert() do modelo PedidoeventofotoModel.
● Redireciona o usuário para a ação update do controlador
PedidoeventofotoController.
Basicamente, essa ação salva as informações de identificação da imagem no banco de
dados para uso posterior.
A função updateAction inicia com a criação de uma nova instância do objeto
Zend_Session_Namespace para recuperar as informações armazenadas na sessão da
aplicação. Em seguida, é criada uma instância do modelo PedidoeventofotoModel e
chamado o método joinUpdate passando o $id_evento como parâmetro. Por fim, é
redirecionado o usuário para a action relatorio do controlador
PedidoeventofotoController.
O método joinUpdate faz uma atualização em massa na tabela sa_pedido_evento_foto.
Ele realiza um join com a tabela sa_pedido_evento, tabela onde os pedidos realizados
pelos usuários são armazenados, com a tabela sa_usuario e a tabela
sa_usuario_balcao. Depois, realiza uma atualização dos dados dos pedidos
identificados na tabela sa_pedido_evento_foto com os dados da tabela
sa_pedido_evento e das tabelas sa_usuario ou sa_usuario_balcao, dependendo do
caso.

Essa atualização é feita em lote, ou seja, é executada em uma única transação no


banco de dados para melhorar a performance. O objetivo é garantir que as
informações identificadas nas imagens sejam atualizadas na base de dados do sistema.
Caso a atualização seja realizada com sucesso, o método retorna true. Caso contrário,
retorna false.

Por fim, a função redireciona o usuário para a ação relatorio da classe


PedidoeventofotoController. Em resumo, a função updateAction atualiza os dados da
tabela sa_pedido_evento_foto com base em informações obtidas de outras tabelas e
redireciona o usuário para outra página.

A função relatorioAction() é um método de uma classe que faz parte de um


framework de desenvolvimento web chamado Zend. O objetivo dessa função é gerar
um relatório de fotos identificadas por evento, com paginação.

Primeiramente, a função cria uma instância de um objeto Zend_Session_Namespace,


que é responsável por armazenar dados de sessão em uma variável global disponível
para a aplicação. Em seguida, ela obtém os parâmetros da requisição feita ao servidor
web e cria uma instância de um objeto PedidoeventofotoModel.

O parâmetro pageNumber é definido de acordo com o valor passado na requisição ou,


caso não haja um valor definido, é atribuído o valor 1. Depois, a função obtém os
dados das fotos identificadas para o evento utilizando o método
getFotosIdentificadasByEventoPaginator() da classe PedidoeventofotoModel.
Esse método recebe como parâmetro o ID do evento, além do número da página atual
e a quantidade de itens por página. Esses dois últimos parâmetros têm valores padrão
de 1 e 10, respectivamente.

O método getFotosIdentificadasByEventoPaginator() faz uma consulta no banco de


dados utilizando a classe Zend_Db_Select para selecionar os dados da tabela
sa_pedido_evento_foto onde o ID do evento é igual ao valor passado como parâmetro.
A consulta é limitada para retornar apenas os itens da página atual, com a quantidade
definida no parâmetro itemsPerPage, e o resultado é retornado em um objeto
Zend_Db_Table_Rowset.

Por fim, a função relatorioAction() define algumas variáveis de visualização para


serem utilizadas na geração do relatório. A variável dados recebe o resultado da
consulta do método getFotosIdentificadasByEventoPaginator(), enquanto a variável
totalPages recebe a contagem de todos os itens retornados pela consulta.

O arquivo relatorio.phtml é um arquivo de visualização em PHP que é renderizado


quando a action relatorioAction é chamada. O objetivo é exibir uma tabela de
informações sobre fotos de eventos que foram identificadas. A tabela é construída
usando um loop foreach que percorre o array $this->dados, que é definido na action
relatorioAction. Cada linha da tabela representa um item em $this->dados, que é um
conjunto de informações sobre uma foto identificada em um evento.

O arquivo também inclui um sistema de paginação que permite navegar pelas várias
páginas da tabela de resultados. A barra de navegação é renderizada com base no
número total de páginas, que é definido em $this->totalPages na action
relatorioAction.

Além disso, o arquivo inclui um botão "Download" que, quando clicado, chama a
action exportar em pedidoeventofoto controller. O script JavaScript abaixo do botão
captura o evento de clique e redireciona o navegador para a URL da ação de
exportação.

O arquivo relatorio.phtml também inclui um pouco de CSS para estilizar a tabela e os


elementos de paginação. O CSS define uma tabela de estilo responsivo e adiciona
algumas cores para distinguir as linhas pares e ímpares. Também adiciona um estilo ao
botão de download.

A função exportarAction() é acionada quando o usuário clica no botão download essa


função é responsável por gerar um arquivo do tipo Excel (.xlsx) contendo os dados de
todas as fotos identificadas pelo evento especificado.

O primeiro passo é criar um objeto PHPExcel, que é a biblioteca utilizada para


manipulação de arquivos Excel em PHP. Em seguida, é adicionada uma planilha ao
objeto, e as colunas e cabeçalhos são definidos.

Depois disso, os dados das fotos identificadas pelo evento são buscados no banco de
dados, e as células da planilha são preenchidas com esses dados. A cada iteração do
loop que percorre os dados, a cor de fundo das células é alternada entre cinza e azul,
para melhorar a visualização da tabela.

Por fim, são definidos os cabeçalhos para download do arquivo XLSX, e o arquivo é
salvo utilizando o objeto PHPExcel_IOFactory. Resumindo, a função exportarAction()
cria um arquivo Excel contendo os dados das fotos identificadas pelo evento
especificado, e disponibiliza esse arquivo para download pelo usuário.

Você também pode gostar