Criando um Data Grid com POO e PHP5

agosto 19, 2009 by admin · Leave a Comment
Filed under: PHP, Programação 

Um data grid nada mais é do que a apresentação de dados em forma de tabela (lembra das <table></table>? Algo assim). Cada conjunto de registros é mostrado em uma linha, e o data grid pode ter funcionalidades de ordenação dos dados e opções para sua edição ou exclusão.

Classe Data Grid PHP

Com esta simples classe é possível criar um data grid a partir de um array com os dados que queremos apresentar na tabela. É simples criar e configurar e, com alguns comandos avançados, é possível alterar o seu comportamento para que seja possível implementar as necessidades habituais em uma estrutura desse tipo.

Essa classe foi criada com POO (Programação Orientada a Objetos) e características que estão disponíveis somente a partir do PHP5. Ela pode ser baixada clicando aqui.

Vamos começar a ver como funciona a classe utilizando um exemplo simples e inserindo funcionalidades no decorrer do artigo, para deixar nosso exemplo mais robusto.

Para começar é necessário inserir a classe nos scripts PHP antes de utilizá-la.

//incluimos a classe

require 'DataGrid.php';

Agora temos que criar um Array com os dados que serão apresentados no Data Grid. Será um array associativo, duas dimensões, onde a primeira, o array principal, receberá todos os registros a serem mostrados no data Grid, e na segunda estão cada um dos registros definidos como um array associativo.

Agora construímos o array com um algumas informações, mais adiante veremos como construir esse array através de uma consulta ao banco de dados.

//criamos o array com os dados a serem apresentados no Data Grid

$alunos = array(

array("id" => 1, "nome" => "Pepe Perez", "curso" => "Informática básica", "nivel" => 2),

array("id" => 2, "nome" => "María Suarez", "curso" => "Informática avançada", "nivel" => 1),

array("id" => 3, "nome" => "Roberto Soriano", "curso" => "Sistemas operacionais", "nivel" => 2),

array("id" => 5, "nome" => "Alberto Rodriguez", "curso" => "Inglés técnico", "nivel" => 1),

array("id" => 7, "nome" => "Julia Marcos", "curso" => "Sociologia", "nivel" => 3),

array("id" => 10, "nome" => "Socorro Rozas", "curso" => "Informática básica", "nivel" => 1),

array("id" => 11, "nome" => "Pablo Reñones", "curso" => "Informática básica", "nivel" => 2)

);

Agora, antes de continuarmos com a construção da estrutura, temos que criar alguns estilos CSS para podermos melhorar o aspecto do Data Grid

<style type="text/css">

.linhaI{background-color:#ffffcc;}

.linhaP{background-color:#ffcc99;}

.fdg_sortable {cursor:pointer;text-decoration:underline;color:#00c;}

</style>

Foram criadas três classes CSS, com seus respectivos estilos. As classes “linhaI” (linha ímpar) e “linhaP” (linha par) aplicaram estilo às linhas do Data Grid e a classe “fdg_sortable” é responsável por estilizar os títulos de cada coluna do Data Grid.

Vamos criar o data grid a partir dos dados que temos no array.

//instanciamos o objeto data grid, passando como parâmetro o array anterior

Fete_ViewControl_DataGrid::getInstance($alunos)

//VAMOS LANÇANDO DIVERSOS MÉTODOS SOBRE O OBJETO INSTANCIADO

//atributos gerais para a tabela

->setGridAttributes(array('cellspacing' => '3?, 'cellpadding' => '4?, 'border' => '0?))

//permitimos que hajam características de ordenação

->enableSorting(true)

//fazemos um setup das colunas do data grid, indicando o valor que será mostrado na primeira linha do data grid

->setup(array(

'id' => array('header' => 'ID'),

'nome' => array('header' => 'Nome'),

'curso' => array('header' => 'Curso'),

'nivel' => array('header' => 'Nivel curso')

))

//definimos os estilos para as linhas ímpares

->setRowClass('linhaI')

//definimos os estilos para as linhas pares

->setAlterRowClass('linhasP')

//chamamos o método que construirá o data grid

->render();

Todas as linhas foram comentadas para que o entendimento se torne mais simples.

Agora vejamos como inserir ou apagar coisas do data grid, para personalizá-lo. Faremos algumas coisas como:

  1. Vamos ocultar o “ID” do array associativo, para que não seja mostrado.
  2. No campo de nível do cursos, vamos mostrar o nível com alguns asteriscos usando uma função que converterá os números em uma cadeia de asteriscos.
  3. Vamos coluna no data grid, que aparecerá antes de qualquer outra, para mostrar um contador que indicará a quantidade de registros apresentados.

Destas três coisas, a mais complicada é fazer um modelo para alterar a forma como é mostrado um campo. Para começar, precisaremos de uma função que devolva o dado que se quer mostrar, com o formato desejado.

function nivel_estrelas($num){

$estrelas = "";

for ($i=0; $i<$num; $i++){

$estrelas .= "*";

}

return $estrelas;

}

Utilizaremos essa função para atribuir como “template” para o campo nível de curso.

Vamos agora ao código utilizado para implementar todas as funcionalidades citadas no data grid:

//OCULTAR UM CAMPO NO DATA GRID

//COLOCAR UMA FUNÇÂO PARA MOSTRAR UM CAMPO

//COLOCAR UM CAMPO ANTES DAS COLUNAS DO ARRAY DO DATA GRID

Fete_ViewControl_DataGrid::getInstance($alunos)

->setGridAttributes(array('cellspacing' => '3?, 'cellpadding' => '4?, 'border' => '0?))

->enableSorting(true)

//fazemos com que o campo "id" do array associativo não seja mostrado

->removeColumn('id')

->setup(array(

'nome' => array('header' => 'Nome'),

'curso' => array('header' => 'Curso'),

//utilizamos a função template para mostrar o nivel do curso com umas estrelas

'nivel' => array('header' => 'Nivel curso', 'cellTemplate' => '[[nivel_estrelas:%data%]]')

))

//inserimos uma coluna em todos os registros do data grid(a primeira coluna será esta)

//nesta coluna mostramos um contador de registros

->addColumnBefore('Contador', '%counter%.', 'Num', array('align' => 'right'))

//definimos a partir de que número será iniciado o contador

->setStartingCounter(1)

->setRowClass('linhaI')

->setAlterRowClass('linhaP')

->render();

Novamente as linhas foram comentadas para facilitar o entendimento. Chamo a atenção sobre a linha que faz uso da função anterior como um template para um campo.

'nivel' => array('header' => 'Nivel curso', 'cellTemplate' => '[[nivel_estrelas:%data%]]')

Isto faz com que o campo “nivel”, quando for mostrado em linhas distintas do data grid, chame a função nivel_estrelas(), passando como parâmetro %data%, que é o valor que tem cada um dos registros do array associativo, no campo “nível”.

Por último vamos ver outro exemplo, um pouco mais desenvolvido, para mostrar os dados do mesmo array. Neste caso vamos simplesmente mostrar uma coluna adicional ao final de cada registro do data grid, onde iremos inserir uns links para editar e/ou apagar o registro atual.

//PARA COLOCAR UM BOTÃO PARA EDITAR OU APAGAR
Fete_ViewControl_DataGrid::getInstance($alunos)
->setGridAttributes(array('cellspacing' => '3?, 'cellpadding' => '4?, 'border' => '0?))
->enableSorting(true)
->removeColumn('id')
->setup(array(
'nome' => array('header' => 'Nome'),
'curso' => array('header' => 'Curso'),
'nivel' => array('header' => 'Nivel curso', 'cellTemplate' => '[[nivel_estrelas:%data%]]')
))
->addColumnBefore('Contador', '%counter%.', 'Num', array('align' => 'right'))
//agora mostro um campo depois de cada elelemto, com links para editar ou apagar o registro
//no interior deste campo utilizo $id$ para enviar o valor "id" do array
->addColumnAfter('actions', '<a href="exemplo3.php?editar=$id$">Editar</a> ?
<a href="exemplo3.php?apagar=$id$" onclick="return confirm('Está certo que quer apagar $nome$?')">Apagar</a>', 'Actions', array('align' => 'center'))
->setStartingCounter(1)
->setRowClass('linhaI')
->setAlterRowClass('linhaP')
->render();

Neste exemplo apenas inserimos uma linha de código para fazer uma chamada ao método addColumnAfter(), que serve para inserir uma coluna depois das colunas que formamos com o array.

->addColumnAfter('actions',
'<a href="exemplo3.php?editar=$id$">Editar</a> ? <a
href="exemplo3.php?apagar=$id$" onclick="return confirm('Está certo que
quer apagar $nome$?')">Apagar</a>', 'Actions', array('align'
=> 'center'))

Neste caso simplesmente temos que indicar como parâmetro a addColumnAfter() dois dados: o primeiro para especificar um título para a coluna e o segundo para especificar o seu conteúdo. O conteúdo dessa coluna, neste caso, são os links para editar e apagar, onde são utilizadas urls que enviam os dados por GET, que é o identificador do registro.

Montando o data grid a partir de um banco de dados

Só falta agora falar sobre como extrair os dados de uma base de dados para fazer o array de elementos que será utilizado na montagem do data grid.

No exemplo que acompanha a classe data_grid há um código para extrair a informação do MySQL, como pode ser visto nas linhas abaixo.

$users = array();

$result = mysql_query("SELECT * FROM user", $dbLinkId);

while ($row = mysql_fetch_assoc($result))

{

$users[] = $row;

}

Como se pode ver, primeiro se cria um array e logo se faz um looping pelos resultados da consulta. Cada um dos elementos retornados pela consulta será introduzido no array criado anteriormente e para ele assinalamos o array associativo que nos devolverá mysql_fetch_assoc() desse primeiro array.

Bom, pessoal, espero que esse artigo possa ser útil a vocês. Clique abaixo para poder fazer o download da classe e de um exemplo.

Clique aqui para baixar a classe data grid junto com um exemplo

Fonte: Imasters

Frameworks no PHP: O que, quando, por que e qual?

julho 29, 2009 by admin · Leave a Comment
Filed under: PHP, Programação 

PHP é a linguagem de programação mais famosa do mundo por várias razões: flexibilidade, facilidade de uso e vários outros fatores. Mas algumas vezes a programação se torna monótona e/ou repetitiva, e é aí que um framework pode ajudar.

O que é um framework de PHP?

De forma resumida o framework é uma estrutura, uma fundação para você criar a sua aplicação. Em outras palavras o framework te permite o desenvolvimento rápido de aplicações (RAD), o que faz economizar tempo, ajuda a criar aplicações mais sólidas e seguras além de reduzir a quantidade de código repetido. Os frameworks também permitem que os iniciantes criem aplicações mais estáveis garantindo uma boa relação entre o banco de dados e a camada externa de exibição. Isso tudo te permite gastar mais tempo desenvolvendo a aplicação em si do que repetindo os códigos que todas as aplicações têm.

A idéia padrão de trabalho por trás de um framework no PHP está ligada ao modelo MVC (Model View Controller). MVC é uma forma de programação que isola a lógica de negócio (como a aplicação funciona) da camada de exibição (a parte visual). O Model cuida do banco de dados, o View cuida da camada de exibição e o Controller cuida da lógica de negócio. Isso tudo faz com que você trabalhe mais rápido e de forma setorizada.

Por que usar um framework de PHP?

Os desenvolvedores utilizam frameworks por vários motivos, e o maior deles é para agilizar o processo de desenvolvimento. A re-utilização de código em vários projetos vai economizar muito tempo e trabalho? Isso é garantido, pois o framework já traz uma série de módulos pré-configurados (e funcionando) para fazer as mais variadas e comuns tarefas como envio de e-mails, conexão com o banco de dados, sanitização (limpeza) de dados e proteção contra ataques.

Estabilidade é outra grande vantagem dos frameworks. A simplicidade, que é um dos grandes “feitos” do PHP, também é o que possibilita inúmeros erros e falhas pelos principiantes? Nem todo código que funciona necessariamente está correto e bem desenvolvido.

Quando usar um framework de PHP?

Essa é uma dúvida muito comum em todos os níveis de desenvolvimento. Para a maioria dos iniciantes, usar um framework, além de ser mais fácil, vai ser mais estável, então é bom usá-los sempre que possível.

Em contrapartida vários programadores experientes vêem os frameworks como ferramentas usadas por programadores fracos, que não sabem como criar um código limpo, sólido e seguro.

Quando se trabalha com projetos que têm um prazo muito curto (o que eu chamo de “prazo Jack Bauer”) é sempre bom usar um framework, pois ele vai agilizar todo o processo. Outro motivo forte para o uso do framework é que você não está criando “código artesanal”? Há todo um padrão que você deve seguir para que as coisas funcionem, e está tudo documentado e explicado em uma vasta comunidade de suporte.

CakePHP

O CakePHP é uma grande opção para iniciantes e desenvolvedores avançados. Ele foi criado usando as bases e modelos do Ruby on Rails e é pesadamente focado no desenvolvimento ágil e rápido. Recentemente ele tem se tornado muito famoso por sua simplicidade e facilidade de uso.

Eu pessoalmente recomendo o CakePHP. Minha vida de programador mudou depois que eu comecei a usar ele.

Zend Framework

O Zend Framework é um framework focado no desenvolvimento de aplicações pra web 2.0. Ele tem um grande número de seguidores, fontes de suporte e uma comunidade cheia de usuários ativos e participativos. O Zend é o framework mais famoso hoje em dia, ele é robusto e permite a criação de aplicações enterprise (de grande porte) mas seu uso exige um conhecimento vasto do PHP.

CodeIgniter

Já o CodeIgniter é bastante conhecido pela sua facilidade de uso, performance e rapidez. É ideal para aplicações rodando em servidores compartilhados. Ele oferece soluções simples e de pequeno porte, com um grande número de tutoriais em vídeo, fóruns e wikis.

Fonte: Imasters

Conectando C# ao MySQL

julho 29, 2009 by admin · Leave a Comment
Filed under: .Net, Banco de Dados, MySQL, Programação 

Quem está habituado a programar C# normalmente utiliza SQL Server como banco de dados, uma vez que ela está integrada no Visual Studio e, por isso mesmo, existe grande facilidade em trabalhar com as duas ferramentas.

Por vezes existem projetos em que se torna conveniente (por várias razões) utilizar outro tipo de base de dados. Seja que banco de dados for, a sua integração é sempre diferente do SQL Server.

Neste caso vou mostrar como fazer a integração entre o C# e o MySQL.

Supondo que já existe uma instalação do MySQL na máquina, precisamos instalar um intermediário entre o C# e a base de dados. Neste caso necessitamos instalar o MySQL Connector NET.

Download

A versão 5.2 já tem suporte ao Visual Studio 2008, mas eu vou utilizar a última versão (6.0).

Instalamos o Connector Net 6.0.

Devemos já ter uma base de dados com uma tabela (users por exemplo), em que os campos da tabela são: id, nome, email.

Como exemplo criamos um projecto Windows Forms Application.

Antes de mais nada, devemos fazer uma referência à classe que vai ligar o C# ao MySQL. Para isso vamos ao painel Solution Explorer, na raiz do projeto, clicamos com o lado direito do mouse e selecionamos Add Reference.

Na primeira divisória (.NET) selecionamos a referência MySQL.Data e damos OK.

Não esquecer: incluir no início do código as classes:

using System.Data;

using MySql.Data.MySqlClient;

Sem adicionar a referência à MySQL.Data, a classe MySql.Data.MySqlClient não será reconhecida.

Para exemplificar fazemos um formulário de inserção de dados (nome e e-mail) na base de dados.

No form colocamos duas caixas de texto, uma para o nome (txtNome) e outra para o e-mail (txtMail) e um botão que terá a ação de inserir os dados na base de dados.

Vamos então definir, em primeiro lugar, o dataset e a string de conexão à base de dados.

private MySqlConnection bdConn; //MySQL
private MySqlDataAdapter bdAdapter;
private DataSet bdDataSet; //MySQL

Na ação do botão:

//Definição do dataset
bdDataSet = new DataSet();
 //Define string de conexão
bdConn = new MySqlConnection("Persist Security  Info=False;server=localhost;database=rfidapp;uid=root;server=localhost;database=rfidapp;uid=root;pwd=''");

Neste caso a base de dados não tem password.

//Abre conecção
 try{
        bdConn.Open();
}
catch{
 MessageBox.Show("Impossível estabelecer conexão");
}
//Verifica se a conexão está aberta
if (bdConn.State == ConnectionState.Open)
{
        //Se estiver aberta insere os dados na BD
MySqlCommand commS = new MySqlCommand("INSERT INTO regists VALUES('',\\'" + txtNome + "\\',\\'" + txtMail + "\\')", bdConn);
commS.BeginExecuteNonQuery();
}

Tome atenção na sintaxe do SQL para o MySQL (INSERT) que é um pouco diferente do C#/SQL Server.

Neste momento o formulário deverá inserir dados no BD.

Fonte: Imasters

O que é o Google Wave?

junho 1, 2009 by admin · Leave a Comment
Filed under: Dicas, Google API, Programação 

O que é o Google Wave?

O Google anunciou, na sexta passada, uma ideia nova e experimental para modificar o futuro da comunicação na Web. O nome é Wave (“Onda”) e, se você acreditar no seu desenvolvedor, é “o que o email seria se fosse inventado hoje”. Além disso, vai ser totalmente open source. Já está intrigado?

Primariamente, o Wave tem como objetivo melhorar a comunicação em tempo real na web. Aqui tem um vídeo de quase hora e meia com a apresentação completa aos desenvolvedores na conferência Google I/O, mas se você não quiser ou não tiver tempo de ver, fique com os detalhes diretamente da boca do Google:

O QUE É UMA WAVE?

Uma wave é conversação e documento em partes iguais. As pessoas podem se comunicar e trabalharem juntos com texto formatado, imagens, vídeos, mapas e mais.

Uma wave é compartilhada. Qualquer participante pode responder em qualquer ponto da mensagem, editar o seu conteúdo e adicionar participantes em qualquer ponto do processo. A função Playback permite que qualquer um retroceda a Wave passo a passo desde o início, para ver quem disse o quê e quando.

Uma wave é viva. Com a transmissão instantânea à medida que você digita, os participantes de uma wave podem ter conversações mais rápidas, ver edições e interagir com extensões em tempo real.

Bastante amplo, né? O Google Wave é claramente algo que precisaremos ver em ação, usar mesmo, antes de entender completamente como funciona. Da mesma forma que o email, o Wave foi desenvolvido como um padrão que poderá ser rodado a partir de qualquer servidor, então ele não vai pertencer ao Google. Qualquer um vai poder ter o seu próprio Wave, e este Wave pode competir com o do Google ou se comportar como o dono quiser. Mas, sendo criado sobre um protocolo padrão, Waves diferentes podem entender e se comunicar entre si, da mesma forma que o Outlook pode trocar emails normalmente com um Thunderbird, GMail ou Yahoo Mail.

Isso resolve um problema que eu (e muitos outros bem mais inteligentes que eu) sempre tive com o Twitter: ele vive nos servidores de uma empresa, e a sua informação está suscetível ao que quer que a empresa queira fazer com ela. RSS, email e mensagens instantâneas trabalham com protocolos padrões que podem ser utilizados por qualquer um. É o exemplo dos emails que eu dei acima.

O blog TechCrunch fez uma análise bem detalhada do Wave (link lá no fim, em inglês) e dos rumos que o Google tomou com ele até agora. O Wave ainda é incrivelmente novo e pouco desenvolvido, mas também é muito intrigante sob o ponto de vista do Futuro-da-Internet e coisa assim. Pode não dar em nada, mas considerando as reações que teve e a popularidade de serviços como o Twitter e o Facebook, a ideia de um protocolo que transforma uma comunicação deste tipo em padrão aberto soa muito promissora.

O Wave não está disponível de nenhuma forma para mim e para você por enquanto, e muito da tecnologia por trás dele depende das atualizações do HTML 5, que não estarão disponíveis pelo menos por mais um pouco de tempo, mas no site oficial você pode se inscrever para atualizações do Google Wave se estiver ansioso por toda e qualquer novidade do desenvolvimento. (N.T.: Eu mais do que certamente estou.)

Fonte: Imasters

Manipulação de dados BLOB com PHP e MySQL

maio 14, 2009 by admin · Leave a Comment
Filed under: PHP, Programação 

Sem dúvida alguma, uma das perguntas mais frequentes em relação ao MySQL é: “como posso armazenar arquivos em uma base de dados?”. A resposta é: tens que usar o tipo de dados BLOB. Estes BLOBs (Binary Large Objects) podem armazenar praticamente qualquer tipo de dados, incluindo documentos do MS Word, imagens gif/jpeg, arquivos PDF, mp3, etc.

Neste artigo vamos ver como criar um repositório de arquivos binários usando PHP e MySQL para poder armazenar diferentes tipos de arquivos. Veremos como armazenar cada um dos arquivos em uma base de dados, para posteriormente recuperá-los.

Para testar os exemplos deste artigo, é necessário ter acesso a um servidor com suporte a PHP, além de contar com um servidor MySQL. Assumindo que você conte com os privilégios apropriados para criar a base dados, e que o MySQL está rodando no mesmo servidor que o PHP, vamos iniciar o desenvolvimento.

Criando a base de dados

Nosso repositório de documentos usará uma base dados que contenha unicamente uma tabela para armazenar todos os documentos. O banco de dados será chamado de “repositorio“, e a tabela de “arquivos“.

Código SQL para criar a tabela

CREATE TABLE arquivos(
id int not null auto_increment primary key,
nome varchar(50),
titulo varchar(50),
conteudo mediumblob,
tipo varchar(50));

Agora temos uma base chamada repositorio, que contém uma tabela chamada arquivos.

Veja abaixo informações sobre cada campo da tabela arquivos:

  • id - um número inteiro que nos proporcionará um identificador único para cada arquivo que iremos armazenar. Este será incrementado automaticamente cada vez que for inserido um novo registro.
  • nome - o nome original do arquivo, por exemplo, fot.gif, curriculum.doc, etc.
  • titulo - uma breve descrição de cada arquivo que será gravada na tabela, por exemplo “Carta para minha noiva”, ou “A foto do meu irmão”. Este título será usado posteriormente na visualização dos arquivos do repositório em uma página web.
  • conteudo – um campo do tipo binário (blob) para guardar o conteúdo de cada arquivo. Na nossa tabela usamos um tipo mediumblob, o qual pode armazenar arquivos de até 16Mb.
  • ipo – como veremos mais adiante, cada arquivo (seja um .doc, .gif, .pdf, etc) tem um tipo único. Quando se envia um
    arquivo para o servidor web através de uma página web, o navegar envia ao servidor a informação acerca do tipo de arquivo, o tipo de conteúdo do arquivo, etc. Os tipos de conteúdo são simples cadeias. O tipo de conteúdo para um arquivo MS WORD é “application/msword”, o tipo de conteúdo para uma imagem é “image/gif”, etc.

Agregando arquivos à base de dados

Agora que temos a base de dados do nosso repositório e sabemos a finalidade de cada campo, vamos criar uma simples página web que permita selecionar um arquivo desde o navegador para posteriormente enviá-lo para um script em PHP que ficará encarregado de armazená-lo em nossa base de dados.A página web será nomeada escolher_arquivo.html e o script em PHP será chamado de guardar_arquivo.php.

A página web pode conter todo o código HTML que se deseje, mas é necessário que se inclua o seguinte formulário para que se tenha a opção de escolher um arquivo e enviá-lo ao servidor.

<!-- ...código anterior -->
<form enctype="multipart/form-data" action="guardar_arquivo.php" method="post">
Descrição <input type="text" name="titulo" size="30">
Arquivo <input type="file" name="arquivo">
<input type="submit" value="Enviar arquivo">
</form>
<!-- ...código posterior -->

Do código que escrevemos temos que frisar o seguinte:

  • o formulário necessita de um atributo enctype com um valor multipart/form-data
  • o método de envio tem que ser POST
  • tem que ser usado pelo menos um campo do tipo FILE

Estes são os três requerimentos básicos que a página HTML deve cumprir para que seja possível enviar o arquivo para o servidor.

Antes de escrever o código do script guarda_arquivo.php, vamos comentar algo acerca da forma como serão recebidos os dados do arquivo em questão.

Desde a versão 4.1 do PHP é recomendada a utilização da variável $_FILES para a leitura dos dados do arquivo que está sendo enviado ao servidor. Abaixo estão listadas os índices e parâmetros recebidos pela variável. Note que o nome dos índices depende de como é nomeado o campo do tipo FILE no formulário.

$_FILES['arquivo']['name']

Nome original do arquivo
$_FILES['arquivo']['type']

O tipo MIME do arquivo, … image/gif, application/pdf, application/msword,.. etc
$_FILES['arquivo']['size']
O tamanho do arquivo em bytes
$_FILES['arquivo']['tmp_name']

O local do arquivo temporário que se cria quando o arquivo é enviado ao servidor. É nesta variável que são lidos todos os dados do arquivo em si. Se estes dados não são copiados ou movidos para outro lugar, ou em nosso caso, armazenados em uma base de dados, podem ser perdidos, já que o PHP elimina esses arquivos depois de um determinado tempo.

Por exemplo, estes são os possíveis valores para um arquivo j-odbc.zip que foi enviado ao servidor:

$_FILES["arquivo"][name] => j-jdbc.zip
$_FILES["arquivo"][type] => application/zip
$_FILES["arquivo"][tmp_name] => /tmp/phpvXQpqP
$_FILES["arquivo"][size] => 337945

Vale ressaltar que devem ser revistos e, se necessário modificar as seguintes variáveis no arquivo de configuração do PHP para que você possa fazer o upload dos arquivos para o servidor, e pode ser gerida por um script PHP.

  • file_uploads – diz ao PHP se pode ou não ser feito o envio de arquivos para o servidor. Essa variável deve ter o valor  “On”.
  • upload_max_filesize – diz ao PHP qual o tamanho máximo do arquivo que pode ser enviado ao servidor. Pode ser utilizado o sufixo “M” para indicar o valor em Megabytes, por exemplo, com um valor 2M se aceita um arquivo máximo de 2 Megabytes.
  • upload_tmp_dir – é o diretório para onde será copiado temporariamente o conteúdo do arquivo quando for enviado ao
    servidor.

Agora é o momento de mostrar o código PHP que vai armazenar o arquivo em nossa base de dados.

/* guardar_arquivo.php */

require("dbconnect.inc.php");

 $arquiivo = $_FILES["arquivo"]["tmp_name"];
 $tamanho = $_FILES["arquivo"]["size"];
 $tipo    = $_FILES["arquivo"]["type"];
 $nome  = $_FILES["arquivo"]["name"];
 $titulo  = $_POST["titulo"];

 if ( $arquivo != "none" )
 {
 $fp = fopen($arquivo, "rb");
 $conteudo = fread($fp, $tamanho);
 $conteudo = addslashes($conteudo);
 fclose($fp); 

 $qry = "INSERT INTO arquivos VALUES
 (0,'$nome','$titulo','$conteudo','$tipo')";

 mysql_query($qry);

 if(mysql_affected_rows($conn) > 0)
 print "O arquivo foi gravado na base de dados.";
 else
 print "Não foi possível gravar o arquivo na base de dados.";
 }
 else
 print "Não foi possível carregar o arquivo para o servidor.";

O arquivo dbconnetc.inc.php contém unicamente as instruções para conexão ao MySQL e selecionar a base de dados que será utilizada.

/* dbconnect.inc.php */

$conn = mysql_connect("localhost","usuário","senha");
 mysql_select_db("repositorio");

Listando os arquivos da base de dados

Já que gravamos alguns arquivos no nosso repositório, agora podemos listar as informações deles, para posteriomente fazermos o download.

/* listar_arquivos.php */

require("dbconnect.inc.php");

$qry = "SELECT id, nome, titulo, tipo FROM arquivos";
$res = mysql_query($qry);

while($fila = mysql_fetch_array($res))
{
print "$fila[titulo]
<br>
$fila[nome] ($fila[tipo])
<br>
<a href='baixar_arquivo.php?id=$fila[id]'>Fazer Download</a>
<br>
<br>";
}

Fazendo o download dos arquivos da base de dados

Como se pode observar no código anterior, foi colocado um link para cada arquivo, chamado baixar_arquivo.php. A funcionalidade deste script será ler os dados dos arquivos que estão gravados na base de dados e enviá-los ao navegador.

Dependendo do tipo de arquivo da qual se trate, o navegador poderá mostrá-lo por ele mesmo o conteúdo do arquivo.

/* Script baixar_arquivo.php */

require("dbconnect.inc.php");

 $qry = "SELECT tipo, conteudo FROM arquivos WHERE id=$id";
 $res = mysql_query($qry);
 $tipo = mysql_result($res, 0, "tipo");
 $conteudo = mysql_result($res, 0, "conteudo");

 header("Content-type: $tipo");
 print $conteudo;

Comentário Finais

Como se pode observar, o código PHP dos scripts é bem simples, e não tem nenhum grau de dificuldade. O código foi desenvolvido com o propósito mais simples possível, para que possa ser melhorado e utilizado em aplicações mais robustas.

Fonte: Imasters

Google Earth no meu site

maio 7, 2009 by admin · Leave a Comment
Filed under: Google API 

O que o Google diz sobre isto?

O plug-in do Google Earth e a API JavaScript permitem incorporar o Google Earth, um verdadeiro globo digital em 3D, nas suas páginas da web. Usando a API, você pode desenhar marcadores e linhas, dispor imagens sobre a área, adicionar modelos em 3D ou carregar arquivos KML, permitindo criar aplicativos sofisticados para mapas em 3D. Se você tem um site de API do Google Maps, pode ativar 3D em sua página com uma única linha de código.

Ótimo, podemos utilizar a API do Google Maps! Vamos ver então um exemplo simples da API do Google Earth e vamos também utilizar o nosso exemplo do artigo anterior (Colocando minha empresa no mapa), onde utilizamos a API do Google Maps, para incluir um novo Servidor de Mapas que será o Google Earth.

Bom, aconselho você ler o artigo anterior antes de seguir, pois necessitamos obter uma chave de segurança da API do Google para utilizá-la neste exemplo. Segue o link (Obtendo uma Chave de API).

Vamos ao Hello, Earth!

Obtendo o Pluggin para rodar o Google Earth no seu browser

Não adianta você ter instalado o Google Earth na sua máquina. Você precisa de um plugin específico para rodar esta API no seu browser.

Para instalar, acesso o link http://code.google.com/apis/earth/ e clique no mapa para baixar o plugin.

Instale o plugin na sua máquina e pronto. Você já pode rodar o Google Earth no seu browser.

Vamos ao código:

<html>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <head>
    <title>Hello Google Earth!</title>
        <!-- Adicionando a API (!!Não esqueça de alterar a sua chave!!)-->
    <script src="http://www.google.com/jsapi?key=SUA_CHAVE_AQUI"></script>
    <script>
        google.load("earth", "1");

        var ge = null;
        // Função Inincial -> Chamada no OnLoad
        function init() {
          // Instancia o Objeto dentro da DIV map3d,
          // caso sucesso, chama a função initCallback, senão, failureCallback
          google.earth.createInstance("map3d", initCallback, failureCallback);
        }
        function initCallback(object) {
          ge = object; //Adiciona o Objeto na variável global ge
          //Dá visibilidade ao Google Earth dentro do navegador.
          ge.getWindow().setVisibility(true);
        }
        function failureCallback(object) { }
    </script>
  </head>
  <body onload='init()' id='body'>
    <center>
      <div id='map3d_container'
           style='border: 1px solid silver; height: 600px; width: 800px;'>
        <div id='map3d' style='height: 100%;'></div>
      </div>
    </center>
  </body>
</html>

Resultado

Pronto, temos apenas um Hello World acima, uma visão do globo geral.

Para visualizar um exemplo de como adicionar controles de navegação, escala, grid, mapa de referência, etc, acesse este link: http://earth-api-samples.googlecode.com/svn/trunk/demos/options/index.html.

É muito simples ampliar as ferramentas do seu mapa.

Integrando o Google Earth API no Google Maps API

Ok, vamos pegar o nosso exemplo do artigo anterior e integrar com o a API Google Earth.

Lembram do código?

Resultado

Alterando o código

- Alteramos as linhas 8,9,10: trocamos a API do Google Maps pela API do Google Earth

- Linha 14: Adicionado o Load da API do Google Maps

- Linha 23: Adicionado o Layer do Google Earth

- Linha 27: Adicionado os controles de layers

Como ficou

Não se esqueça, acesse o site dos desenvolvedores, http://code.google.com/intl/pt-BR/apis/earth/, e visualize os exemplos e as referências das APIs do Google Maps e Google Earth. Apenas com os exemplos disponibilizados pelo Google você aumenta a qualidade do seu site sem muito esforço.

Fonte: Imasters

Barra de Progresso com AJAX

abril 30, 2009 by admin · Leave a Comment
Filed under: JavaScript/Ajax, Programação 

Uma das necessidades com que nos deparamos na hora de realizar projetos longos na web é indicar ao usuário o quanto é preciso esperar. Às vezes é bastante complicado criar uma barra de progresso que mostre o estado atual do processo que está sendo executado.

Uma forma de realizar essa tarefa é usando AJAX. Fazemos uma chamada AJAX que executa a ação, e quando o objeto AJAX tem o estado LOADING (readyState == 3), podemos obter a resposta do script chamado e passá-lo para mostrar o percentual da ação que está sendo realizada.

Para isso, desenvolveremos um script (res. php, por exemplo) que devolva a porcentagem seguida por um hífen. Por exemplo, quando passar por 1% será retornado pelo script “1-”, quando passar por 5% será retornado “1-2-3-4-5″. Processando isso podemos saber, através do último número, o percentual já processado.

O PHP seria o seguinte:

for($i=0; $i<10000000; $i++) {
  if ($i%10000 == 0) echo ((int) $i/100000).'-';
  flush();
} 

E o JavaScript seria assim:

function ajaxobj() {  
  try {  
    _ajaxobj = new ActiveXObject("Msxml2.XMLHTTP");  
  } catch (e) {  
  try {  
    _ajaxobj = new ActiveXObject("Microsoft.XMLHTTP");  
  } catch (E) {  
    _ajaxobj = false;  
  }  
}  

 if (!_ajaxobj && typeof XMLHttpRequest!='undefined') {  
   _ajaxobj = new XMLHttpRequest();  
 }  

 return _ajaxobj;  
}
function prueba () {  
  ajax = ajaxobj();  
  ajax.open("GET", "res.php", true);  
  ajax.onreadystatechange=function() {
  if (ajax.readyState == 3) {  

   // Mostramos o percentual 
   var res = ajax.responseText;
   res = res.split('-');  
   alert(res[res.length-2]);  
  } else if (ajax.readyState == 4) {  

  // Fim
  alert('FIM');  
 }  
}  

 // Enviamos algo para que o processo funcione
 ajax.send(null);  
}  

Como não existe nada perfeito, e menos ainda o Internet Explorer, esse script só funcionou no Firefox, Opera, Safari e Chrome.

Fonte: Imasters

Colocando minha empresa no mapa…

abril 27, 2009 by admin · Leave a Comment
Filed under: Google API, JavaScript/Ajax, Programação 

Este artigo, por mais simples que seja, tende a ser uma das maiores dúvidas e desejos dos usuários que estão iniciando nesta área. Como colocar minha empresa, estabelecimento, casa etc., no mapa. Com certeza no seu site é muito importante existir além do endereço da sua empresa um pequeno mapa representando tudo que está em volta dela para que os usuários possam se localizar mais facilmente.

Nosso foco hoje é criar um mapa utilizando a API do Google Maps. Com isso, não precisamos de nenhum banco de dados geográfico ou qualquer outro tipo de aplicação para desenvolvimento de mapas além das linguagens HTML e JavaScript.

Segundo o próprio Google, o que é a API do Google Maps?

A API do Google Maps permite usar JavaScript para incorporar o Google Maps em sua página da web. A API fornece diversos utilitários para manipular mapas (como na página http://maps.google.com) e adicionar conteúdo ao mapa através de diversos serviços. Você pode criar aplicativos de mapas robustos em seu site.

Passo 1: Obtendo uma chave para a API do Google Maps.

Para utilizarmos a API do Google, precisamos obter uma chave de identificação para o nosso site. É muito importante que você coloque a URL correta do caminho onde estará o mapa, caso contrário, ao instanciar a API no seu código, ela não funcionará.

Acesse o link : http://code.google.com/intl/pt-BR/apis/maps/signup.html, preencha as informações da URL do seu site e clique em GERAR chave de API. Não se esqueça de ler os termos de uso da API, nada de utilizá-la dentro de intranets.

Obs.: Você precisa ter um usuário cadastrado no Google para obtê-la.

Pronto, chave gerada, podemos ir para o próximo passo.

Passo 2: Obtendo o XY da sua empresa

Inicialmente, para identificarmos a sua empresa/estabelecimento/etc no mapa, precisamos da localização correta dela. A localização que comento é com relação ao seu XY. Mas o que é XY? Vamos à matemática…

Para a construção do modelo da superfície topográfica de uma dada região, necessitamos das triplas (x, y, z) de uma série de pontos da superfície do terreno. Os valores (x, y, z) são as coordenadas cartesianas de um ponto P, relativas a um sistema de coordenadas preestabelecido (como já vimos em meu outro artigo Sistemas de Informação Geográfica).

O plano XY é o plano horizontal de referência relativamente ao nível médio dos mares, e z é a distância vertical do ponto P ao plano horizontal XY (se me permitem exemplificar desta maneira, seria a altura em relação ao nível do mar, no nosso caso, não será necessária).

Como posso obter este ponto?

Existem diversas maneiras de se obter o XY de um endereço, vou exemplificar duas: a primeira é suscetível a alguns erros, motivo pelo qual o mapeamento da numeração das ruas nas cidades do Brasil não ser de fato correto (mas confesso que é satisfatório). O que quero dizer é que muitas vezes quando você informa o seu endereço, por exemplo o número 567, seriam 567 metros do ponto inicial da sua rua, nem sempre esta numeração irá bater exatamente no local da sua casa (quando digo exatamente, ainda considero um erro de 50m). Pode acontecer de aparecer na quadra errada; quando ocorrer, sugiro utilizar o segundo exemplo de aquisição do XY.

A primeira maneira que me refiro é solicitar através da url http://maps.google.com/maps/geo?q=STRING+DO+ENDERECOoutput=xmlkey=SUA_CHAVE

Obs.: Separe a string com “+”.

Exemplo:

http://maps.google.com/maps/geo?q=avenidaipiranga1200portoalegrersbrasiloutput=xmlkey=

Exemplo da resposta (response) em XML:

Pronto, seu XYZ é a coordenada <coordinates>-51.2093204,-30.0451247,0</coordinates> .

Agora você pode pular o segundo exemplo e ir direto ao passo 3, mas antes vamos verificar se o ponto está mesmo no local correto.

Acesso o seguinte link:

http://maps.google.com.br/maps?f=qsource=s_qhl=pt-BRgeocode=q=(-30.0451247,-51.2093204)

OBS: Lembre-se de alterar a ordem dos pontos XY <-> YX

A segunda maneira de se obter as coordenadas XY é implementar um outro exemplo utilizando a API do Google Maps. Chamamos este exemplo de Geocode Reverso (através de um clique no mapa iremos obter as informações quanto a este local).

O exemplo abaixo está presente na página da API do Google Maps, mantive-o como o qual para explicar cada linha.

Código

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>Google Maps JavaScript API Example: 	Reverse Geocoder</title>
    <script src="http://maps.google.com/maps?file=apiv=2.xkey=ABQIAAAAzr2EBOXUKnm_jVnk0OJI7xSosDVG8KKPE1-m51RBrvYughuyMxQ-i1QfUnH94QxWIa6N4U6MouMmBA"
            type="text/javascript"></script>
    <script type="text/javascript">

    var map;
    var geocoder;
    var address;

    function initialize() {
      map = new GMap2(document.getElementById("map"));
      map.setCenter(new GLatLng(-30.0270583,-51.2303402), 10);
      map.addControl(new GLargeMapControl);
      GEvent.addListener(map, "click", getAddress);
      geocoder = new GClientGeocoder();
    }

    function getAddress(overlay, latlng) {
      if (latlng != null) {
        address = latlng;
        geocoder.getLocations(latlng, showAddress);
      }
    }

    function showAddress(response) {
      map.clearOverlays();
      if (!response  response.Status.code != 200) {
        alert("Status Code:"  response.Status.code);
      } else {
        place = response.Placemark[0];
        point = new GLatLng(place.Point.coordinates[1],
                            place.Point.coordinates[0]);
        marker = new GMarker(point);
        map.addOverlay(marker);
        marker.openInfoWindowHtml(
        '<b>orig latlng:</b>'  response.name  '<br/>'
        '<b>latlng:</b>'  place.Point.coordinates[1]  ","  place.Point.coordinates[0]  '<br>'
        '<b>Status Code:</b>'  response.Status.code  '<br>'
        '<b>Status Request:</b>'  response.Status.request  '<br>'
        '<b>Address:</b>'  place.address  '<br>'
        '<b>Accuracy:</b>'  place.AddressDetails.Accuracy  '<br>'
        '<b>Country code:</b> '  place.AddressDetails.Country.CountryNameCode);
      }
    }
    </script>
  </head>

  <body onload="initialize()">
    <div id="map" style="width: 500px; height: 400px"></div>
  </body>
</html>

Você já viu um exemplo da resposta (response) em XML no exemplo anterior.

Exemplo da resposta (response) em JSON:

Através dos arquivos acima, você consegue identificar quais as variáveis necessárias para obter os dados do geocode.

Por fim e não menos importante, o corpo do HTML:

<body onload="initialize()">
    <div id="map" style="width: 500px; height: 400px"></div>
        <div id="temp"></div>
  </body>

Não se esqueça de utilizar o ONLOAD para chamar a função initialize() para tão logo carregar a página iniciar o procedimento da criação do mapa. Não quero ver ninguém comentando que o mapa não aparece!

Pronto, agora navegue no mapa, procure o endereço da sua empresa (ainda não criamos uma barra de pesquisa de endereço, nos próximos artigos irei explicar como), clique no local e copie as informações da linha latlng.

Agora temos o XY para continuar no nosso artigo.

Passo 3: Adicionando minha empresa no mapa

Bom, se você já criou o exemplo anterior do geocode reverso, este agora é muito mais simples. Caso contrário, vamos lá passo a passo.

Vamos ao código

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Google Maps JavaScript API Example: Simple Markers</title>
    <script src="http://maps.google.com/maps?file=apiamp;v=2amp;key=
	ABQIAAAAzr2EBOXUKnm_jVnk0OJI7xSosDVG8KKPE1-m51RBrvYughuyMxQ-i1QfUnH94QxWIa6N4U6MouMmBA"
            type="text/javascript"></script>
    <script type="text/javascript">
    function initialize() {
      if (GBrowserIsCompatible()) { // Verifica se o browser é compativel com a API do Google
	    // Instância a API do Google e a adiciona na DIV map.
        var map = new GMap2(document.getElementById("map"));
		// Centraliza o mapa no XY, zoom 16 em uma escala de [1..17] (Varia de acordo com a região)
        map.setCenter(new GLatLng(-30.0451247,-51.2093204), 16);
		// (OPCIONAL) Adiciona os controle de a esquerda do Mapa (Zoom , Zoom -, barra de Zoom, etc)
        map.addControl(new GLargeMapControl);
		// Padronizamos o XY de acordo com o latlng da API: (Y,X)
        var latlng = new GLatLng(-30.0451247,-51.2093204);
        map.addOverlay(new GMarker(latlng)); // Adiciona o marker no mapa
      }//if
    }//function
    </script>
  </head>
  <body onload="initialize()" onunload="GUnload()">
    <div id="map" style="width: 500px; height: 300px"></div>
  </body>
</html>

OBS: Não se esqueça de trocar a sua chave da API. Não se esqueça de declarar o ONLOAD, para que a função initialize(), no meu exemplo, crie o mapa assim que a página seja carregada.

Resultado

Caso você queira incrementar o seu mapa e adicionar um evento de clique no marker, façamos algumas modificações no código:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Google Maps JavaScript API Example: Simple Markers</title>
    <script src="http://maps.google.com/maps?file=api&v=2&key=
	ABQIAAAAzr2EBOXUKnm_jVnk0OJI7xSosDVG8KKPE1-m51RBrvYughuyMxQ-i1QfUnH94QxWIa6N4U6MouMmBA"
            type="text/javascript"></script>
    <script type="text/javascript">
    function initialize() {
      if (GBrowserIsCompatible()) { // Verifica se o browser é compativel com a API do Google
	    // Instância a API do Google e a adiciona na DIV map.
        var map = new GMap2(document.getElementById("map"));
		// Centraliza o mapa no XY, zoom 16 em uma escala de [1..17] (Varia de acordo com a região)
        map.setCenter(new GLatLng(-30.0451247,-51.2093204), 16);
		// (OPCIONAL) Adiciona os controle de a esquerda do Mapa (Zoom +, Zoom -, barra de Zoom, etc)
        map.addControl(new GLargeMapControl);
		// Padronizamos o XY de acordo com o latlng da API: (Y,X)
        var latlng = new GLatLng(-30.0451247,-51.2093204);
		var marker = new GMarker(latlng); // Criamos um marker referenciado a uma variável
		// Criamos um evento para ao se clicar no marker
		GEvent.addListener(marker, "click", function() {
			// Abrir um InfoWindow com o seguinte texto
           marker.openInfoWindowHtml("Endereço da minha empresa! <br/> <strong>;)</strong>");
          });
        map.addOverlay(marker); // Adiciona o marker no mapa
      }//if
    }//function
    </script>
  </head>
  <body onload="initialize()" onunload="GUnload()">
    <div id="map" style="width: 500px; height: 300px"></div>
  </body>
</html>

Pronto!

Adobe Flex – Como colocar gráficos em repeater

abril 14, 2009 by admin · 1 Comment
Filed under: FLEX, Programação 

Estou desenvolvendo um modelo de Dashboard de Indicadores de Performace (KPI) utilizando o Adobe Flex, Asp.NET e SQL Server 2000.

Nesse Dashboard eu precisava exibir vários gráficos de acordo com o perfil de cada usuário. Por isso, construir um modelo fixo não seria possível. Então busquei maneiras de fazer isso utilizando o mx:Tile e o mx:Repeater.

Na busca encontrei apenas um exemplo de Datagrid em um Repeater, com isso foi possível construir o modelo para utilizar com Gráficos.

Primeiro é preciso entender a estrutura de DataProvider, necessária para que tudo funcione como o esperado.

Como na figura acima, o DataProvider é um ArrayCollection composto de um ArrayCollection para cada gráfico que será exibido no Repeater, cada um desse segundo ArrayCollection é composto por objetos que serão os pontos dos gráficos.

Abaixo está o código responsável pela configuração do ArrayCollection, que será o DataProvider do mx:Repeater.

<mx:Script>
        <![CDATA[
                import mx.utils.ObjectProxy;
                import mx.core.Application;
                import mx.utils.ObjectUtil;
                import mx.rpc.events.FaultEvent;
                import mx.rpc.events.ResultEvent;
                import mx.collections.ArrayCollection;

                //ArrayCollection que será o DataProvider do Repeater
                [Bindable]
                private var arDadosGraficoTotal:ArrayCollection = new ArrayCollection();

                private function load():void
                {
                        var arDadosGrafico:ArrayCollection;
                        var obDadosGrafico:ObjectProxy;

                        //Gráfico 1
                        //arDadosGrafico recebe um novo ArrayCollection
                        arDadosGrafico = new ArrayCollection();
                        //obDadosGrafico recebe um novo ObjectProxy
                        obDadosGrafico = new ObjectProxy();
                        //Cria a propriedade data1 e atribiu o 10, data1 será uma série no gráfico
                        obDadosGrafico.data1 = 10;
                        //Cria a propriedade data2 e atribiu o 5, data2 será outra série no gráfico
                        obDadosGrafico.data2 = 05;
                        //Cria a propriedade label e atribiu 'Jan', label será o eixo X do gráfico
                        obDadosGrafico.label = 'Jan';                   

//Cria a propriedade titulo e atribiu 'Vendas', titulo será o titulo do
gráfico, só existirá essa propriedade no primeiro ObjectProxy
                        obDadosGrafico.titulo = 'Vendas';      
                        //Adiciona o ObjectProxy obDadosGrafico ao ArrayCollection arDadosGrafico      
                        arDadosGrafico.addItem(obDadosGrafico);

//obDadosGrafico recebe um novo ObjectProxy e receberá os mesmas
propriedades porém com valores distintos e também é inserido ao
ArrayCollection arDadosGrafico
                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 05;
                        obDadosGrafico.data2 = 05;
                        obDadosGrafico.label = 'Fev';                  
                        arDadosGrafico.addItem(obDadosGrafico);

                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 03;
                        obDadosGrafico.data2 = 05;
                        obDadosGrafico.label = 'Mar';                  
                        arDadosGrafico.addItem(obDadosGrafico);

                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 06;
                        obDadosGrafico.data2 = 05;
                        obDadosGrafico.label = 'Abr';                  
                        arDadosGrafico.addItem(obDadosGrafico);

//Quando terminam os pontos do gráfico é necessário inserir o
ArrayCollection arDadosGrafico ao ArrayCollection arDadosGraficoTotal
                        arDadosGraficoTotal.addItem(arDadosGrafico);    

//Os passos anteriores devem ser feitos para cada gráfico que se deseja
exibir no Dashboard, abaixo estão identificos como Gráfico 2 e Gráfico 3
                        //Gráfico 2
                        arDadosGrafico = new ArrayCollection();
                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 07;
                        obDadosGrafico.data2 = 02;
                        obDadosGrafico.label = 'Jan';                  
                        obDadosGrafico.titulo = 'Custos';                      
                        arDadosGrafico.addItem(obDadosGrafico);

                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 08;
                        obDadosGrafico.data2 = 02;
                        obDadosGrafico.label = 'Fev';                  
                        arDadosGrafico.addItem(obDadosGrafico);

                        obDadosGrafico = new ObjectProxy();

                        obDadosGrafico.data1 = 05;
                        obDadosGrafico.data2 = 02;
                        obDadosGrafico.label = 'Mar';                  
                        arDadosGrafico.addItem(obDadosGrafico);

                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 04;
                        obDadosGrafico.data2 = 02;
                        obDadosGrafico.label = 'Abr';                  
                        arDadosGrafico.addItem(obDadosGrafico);

                        arDadosGraficoTotal.addItem(arDadosGrafico);    

                        //Gráfico 3
                        arDadosGrafico = new ArrayCollection();
                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 10;
                        obDadosGrafico.data2 = 08;
                        obDadosGrafico.label = 'Jan';                  
                        obDadosGrafico.titulo = 'Produção';                    
                        arDadosGrafico.addItem(obDadosGrafico);

                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 12;
                        obDadosGrafico.data2 = 08;
                        obDadosGrafico.label = 'Fev';                  
                        arDadosGrafico.addItem(obDadosGrafico);

                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 06;
                        obDadosGrafico.data2 = 08;
                        obDadosGrafico.label = 'Mar';                  
                        arDadosGrafico.addItem(obDadosGrafico);

                        obDadosGrafico = new ObjectProxy();
                        obDadosGrafico.data1 = 08;
                        obDadosGrafico.data2 = 08;
                        obDadosGrafico.label = 'Abr';                  
                        arDadosGrafico.addItem(obDadosGrafico);

                        arDadosGraficoTotal.addItem(arDadosGrafico);    

//Ao terminado de incluir todos os arDadosGrafico ao
arDadosGraficoTotal, é necessário declarar arDadosGraficoTotal como
dataProvider do repeater
                        rpGrafico.dataProvider = arDadosGraficoTotal;  
                }               

        ]]>
</mx:Script>

Abaixo está o código necessário para exibir os gráficos. Inicialmente foi utilizado um Tile e dentro um Repeater. Dentro do Repeater há um Panel e dentro do Panel está o gráfico que deve ser exibido de acordo com o dataProvider.

Como demonstrado acima, o dataProvider é associado ao término da função load(). Após a associação, o Repeater começará a renderizar o primeiro gráfico, e já no título do Panel o valor atribuído será a propriedade título definida no primeiro objeto do arDadosGrafico.

Para isso é utilizada a instrução: {rpGrafico.currentItem.getItemAt(0).titulo}, ou seja, rpGrafico é o Repeater, a propriedade currentItem contém o arDadosGrafico do laço em questão e getItemAt(0) assegura que só buscará a propriedade título no primeiro objeto dentro do arDadosGrafico.

Para o gráfico, só resta associar um dataProvider a ele para que sejam exibidos os seus pontos. O dataProvider em questão será o currentItem do Repeater rpGrafico, pois como dito acima, a propriedade currentItem contém o arDadosGrafico do laço em questão.

No eixo X, horizontalAxis, é definido label como o campo fonte dos dados. No eixo Y, verticalAxis, está configurado para não começar em zero. Logo abaixo estão as duas séries, uma para o data1 (Indicador Técnico) e outra para data2 (Meta).

<mx:Tile left="10" right="10" top="10" bottom="10" direction="horizontal">
        <mx:Repeater id="rpGrafico" width="100%">
        <mx:Panel width="250" height="200" layout="absolute" id="pnGrafico" title="{rpGrafico.currentItem.getItemAt(0).titulo}">

<mx:LineChart id="grIndicador" dataTipMode="single"
showDataTips="true" dataProvider="{rpGrafico.currentItem}" width="95%"
height="95%" horizontalCenter="0" verticalCenter="0">
                        <mx:horizontalAxis>
                        <mx:CategoryAxis categoryField="label" />                              
                </mx:horizontalAxis>                                                                            
                        <mx:verticalAxis>
                                <mx:LinearAxis baseAtZero="false"/>
                        </mx:verticalAxis>                                                                              
                        <mx:series>                    
                        <mx:LineSeries form="segment" yField="data2" displayName="Meta"/>

                        <mx:LineSeries form="segment" yField="data1" displayName="Indicador Técnico"/>
                        </mx:series>
                </mx:LineChart>
        </mx:Panel>
        </mx:Repeater>
</mx:Tile>

Antes de executar o projeto e ver tudo funcionando legal, é necessário adicionar o código abaixo na segunda linha do código dentro da tag mx:Application

creationComplete=”load()”

Deixando-a assim:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="load();">

Execute o projeto, você deve obter um resultado igual a imagem abaixo.

Complementando?

Para incluir as legendas basta adicionar logo após o gráfico o código abaixo:

<mx:Legend dataProvider="{grIndicador[0]}" bottom="10" left="10" right="10" height="25"/>

Fonte: Imasters

Crie Arquivos .ZIP com ASP.NET

abril 14, 2009 by admin · Leave a Comment
Filed under: .Net, Programação 

Neste artigo vou mostrar como criar arquivos .ZIP e como descompactar utilizando o ASP.net. Imagem de exemplo do exemplo deste artigo.Imagem de exemplo do exemplo deste artigo.

Um pouco de conhecimento antes de programarmos

Arquivos .zip é um formato muito conhecido. Em Matemática, um dos modos de se obter uma compressão de arquivos, é através de Transformada de Fourier. A compressão e compactação são importantíssimas para conseguirmos informações em tempos menores de transmissão, de forma mais barata possível.

Qual a diferença entre Compressão e Compactação?

A principal diferença entre os dois termos é que compactação não há perda de informação, enquanto que na compressão há perda. O Formato .MP3 é um exemplo de Compressão, pois há perda de informação, embora nossos ouvidos não notem muito. Mesmo entre os Mp3, temos aqueles com maior qualidade (menos perda) e os de menores qualidades (maior perda).

Entre os métodos mais conhecidos de compactação estão:

  • Codificação por carreira
  • Codificação por Shannon-Fano
  • Codificação de Huffman (muito utilizado para compactar texto)
  • Codificação de Lempel-Ziv-Welch (LZW)
  • Codificação aritmética

Entre os métodos mais conhecidos de compressão estão:

  • Redução do domínio
  • Redução do espaço de quantização
  • Codificação preditiva
  • Codificação por sub-bandas
  • Codificação por transformadas
  • Quantização vetorial

Pré-requisitos

Este artigo foi montado nas configurações abaixo. Não foi testado em outros ambientes.

  • Framework ASP.NET 2.0 com VB.net
  • Visual Studio 2005.

Mãos a obra

Clique aqui para dar download no projeto de exemplo.

Primeiro, crie uma solução no seu VisualStudio. Adicione um novo projeto Web, e referencie a Biblioteca SharpZLib.

Caso você esteja usa utilizando a versão Express, crie um novo website, e coloque ICSharpCode.SharpZipLib.dll na pasta /bin.

Em seguida, vamos criar uma página chamada zip.ASPX.

Compactando Diretório Inteiro

Para compactar o diretório, você terá que informar o diretório de origem e o arquivo de destino.


''' <summary>
    ''' Evento do botão, gerar diretório
    ''' </summary>
    Protected Sub btnGerar_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGerar.Click
        gerarZipDiretorio(txtOrigem.Text, txtDestino.Text)
        subInitDescompactarArquivos()
    End Sub

    ''' <summary>
    ''' Este método gera um zip, a partir de um diretório
    ''' </summary>
    ''' <param name="sDiretorioOrigem">
    ''' Diretório que será zipado
    ''' </param>
    ''' <param name="sDiretorioDestino">
    ''' Diretório que receberá o arquivo zipado
    ''' </param>
    ''' <remarks>
    ''' </remarks>
    Public Sub gerarZipDiretorio(ByVal sDiretorioOrigem As String, ByVal sDiretorioDestino As String)

        Dim sz As New FastZip()
        Dim sArquivoZip As String = String.Empty

        ' Aqui vou criar um nome do arquivo, com 6 caracteres randômicos.
        ' O Guid é um método do .net que gera string aleatórias únicas, baseada na hora e no
        ' endereço MAC na máquina gerada.
        sArquivoZip = "MeuZip" & Left(Guid.NewGuid.ToString, 6) & ".zip"

        ' Só um tratamento para garantir mais estabilidade
        If Right(sDiretorioOrigem, 1) <> "\" Then
            sDiretorioOrigem = sDiretorioOrigem & "\"
        End If

        ' Só um tratamento para garantir mais estabilidade
        If Right(sDiretorioDestino, 1) <> "\" Then
            sDiretorioDestino = sDiretorioDestino & "\"
        End If

        If Not Directory.Exists(sDiretorioDestino) Then
            lblErro.Text = "O Diretório de Destino informado não existe: <br />" & sDiretorioDestino
            Exit Sub
        End If

        If Not Directory.Exists(sDiretorioOrigem) Then
            lblErro.Text = "O Diretório de Origem informado não existe: <br />" & sDiretorioOrigem
            Exit Sub
        End If

        sz.CreateZip(sDiretorioDestino & sArquivoZip, sDiretorioOrigem & "" & "\", True, "", "")

        ' Aqui eu habilito o download do arquivo.
        ' Muito útil se você quiser salvar em diretórios protegidos
        ' Ou não acessível pela raíz do seu projeto web.
        HttpContext.Current.Response.TransmitFile(sDiretorioDestino & sArquivoZip)

        ' "Limpo" o objeto
        sz = Nothing

    End Sub

Obs.:

Você pode definir uma senha para seu .zip, utilizando a propriedade “password”.

Compactando Somente um Arquivo

Para compactar somente um arquivo, você terá que informar o arquivo a ser compactado, e o diretório de destino.


    ''' <summary>
    ''' Evento do botão gerar Arquivo
    ''' </summary>
    Protected Sub btnGerarArquivo_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGerarArquivo.Click
        gerarZipArquivo(txtArquivoOrigem.Text, txtArquivoDestino.Text)
        subInitDescompactarArquivos()
    End Sub

    ''' <summary>
    ''' Este método gera um zip, a partir de um diretório
    ''' </summary>
    ''' <param name="sArquivoOrigem">
    ''' Arquivo que será zipado
    ''' </param>
    ''' <param name="sDiretorioDestino">
    ''' Diretório que receberá o arquivo zipado
    ''' </param>
    ''' <remarks>
    ''' </remarks>
    Public Sub gerarZipArquivo(ByVal sArquivoOrigem As String, ByVal sDiretorioDestino As String)

        Dim sz As New FastZip()
        Dim sArquivoZip As String = String.Empty

        ' Aqui vou criar um nome do arquivo, com 6 caracteres randômicos.
        ' O Guid é um método do .net que gera string aleatórias únicas, baseada na hora e no
        ' endereço MAC na máquina gerada.
        sArquivoZip = "MeuZip" & Left(Guid.NewGuid.ToString, 6) & ".zip"

        ' Só um tratamento para garantir mais estabilidade
        If Right(sDiretorioDestino, 1) <> "\" Then
            sDiretorioDestino = sDiretorioDestino & "\"
        End If

        If Not Directory.Exists(sDiretorioDestino) Then
            lblErroArquivo.Text = "O Diretório de Destino informado não existe: <br />" & sDiretorioDestino
            Exit Sub
        End If

        If Not File.Exists(sArquivoOrigem) Then
            lblErroArquivo.Text = "O Arquivo de Origem informado não existe: <br />" & sArquivoOrigem
            Exit Sub
        End If

        ' Crio um arquivo do tipo stream, aprontando para o meu zip de destino.
        Dim strmZipOutputStream As ZipOutputStream
        strmZipOutputStream = New ZipOutputStream(File.Create(sDiretorioDestino & sArquivoZip))

        ' Seto o nível de compressão (0->Sem compressão / 9-> Compressão Máxima)
        strmZipOutputStream.SetLevel(9)

        ' Leio o arquivo de origem
        Dim strmFile As FileStream = File.OpenRead(sArquivoOrigem)
        Dim abyBuffer(strmFile.Length - 1) As Byte

        strmFile.Read(abyBuffer, 0, abyBuffer.Length)

        ' Aqui eu trato para pegar somente o arquivo, sem os diretórios
        ' O split é um método que separa a string, de acordo com um caractere, no meu caso "\"
        ' Cada indice da minha matriz é um diretório, e o ultimo é o arquivo
        Dim sAuxArquivo As String() = Split(sArquivoOrigem, "\")

        ' Crio uma variável, adicionando o meu Arquivo ao Zip
        ' Com ubound, eu pego o ultimo índice da minha matriz, que é o nome do meu arquivo.
        Dim objZipEntry As ZipEntry = New ZipEntry(sAuxArquivo(UBound(sAuxArquivo)))

        ' Seto a data de criação
        objZipEntry.DateTime = DateTime.Now

        ' Informo o tamanho do stream. (Do meu arquivo a ser zipado)
        objZipEntry.Size = strmFile.Length

        ' Fecho meu stream para liberar memória
        strmFile.Close()

        ' Adiciono no objeto para gerar o zip.
        strmZipOutputStream.PutNextEntry(objZipEntry)
        strmZipOutputStream.Write(abyBuffer, 0, abyBuffer.Length)

        ' "Limpo" o objeto
        strmZipOutputStream.Finish()
        strmZipOutputStream.Close()

        ' Aqui eu habilito o download do arquivo.
        ' Muito útil se você quiser salvar em diretórios protegidos
        ' Ou não acessível pela raíz do seu projeto web.
        HttpContext.Current.Response.TransmitFile(sDiretorioDestino & sArquivoZip)

    End Sub

Descompactando um arquivo .zip

Para descompactar um arquivo .zip você terá que informar o arquivo, e o diretório de destino.



    Protected Sub btnDescompactar_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnDescompactar.Click
        descompactarZip(txtArquivoParaDescompactar.Text, txtDescompactarArquivos.Text)
    End Sub

    ''' <summary>
    ''' Sub que descompacta um arquivo .zip apra um diretório
    ''' </summary>
    ''' <param name="sArquivoZip">
    ''' Arquivo para ser descompactado
    ''' </param>
    ''' <param name="sDiretorioParaDescompactar">
    ''' Diretório para ser descompactado
    ''' </param>
    ''' <remarks></remarks>
    Private Sub descompactarZip(ByVal sArquivoZip As String, ByVal sDiretorioParaDescompactar As String)

        Dim oMeuZip As New FastZip

        ' Se o arquivo não existe eu aviso o usuário
        If Not File.Exists(sArquivoZip) Then
            lblErroDescompactar.Text = ("Arquivo zip não existe: " & sArquivoZip)
            Exit Sub
        End If

        ' Se o arquivo não for zip, eu aviso o usuário
        If LCase(Right(sArquivoZip, 3)) <> "zip" Then
            lblErroDescompactar.Text = ("Arquivo não é do formato .zip: " & sArquivoZip)
            Exit Sub
        End If

        ' Se o arquivo não for zip, eu aviso o usuário
        If Not Directory.Exists(sDiretorioParaDescompactar) Then
            lblErroDescompactar.Text = ("Diretório para descompactar os arquivos não existe: " & sDiretorioParaDescompactar)
            Exit Sub
        End If

        ' "Deszipo" o arquivo, sem nunca sobrescrever
        oMeuZip.ExtractZip(sArquivoZip, sDiretorioParaDescompactar, FastZip.Overwrite.Never)

        lblErroDescompactar.Text = "Arquivo Descompactado com sucesso!!!!!"
    End Sub

Para você testar!

Para que você possa testar, colocamos um formulário, e um código de inicialização da página.

Formulário:


<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Criar Arquivos Zip em Asp.Net</title>
    <style type="text/css">
    body, input{
    font-family: verdana;
    font-size: 10px;
    }

    </style>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <strong>Este exemplo utiliza componentes de terceiros. Verifique o termo de uso.
                .</strong>
            <br />
            <br />
            <fieldset>
                <legend>Criar Arquivo Zip do Diretório Inteiro </legend>
                <table style="border: none;">
                    <tr>
                        <td>
                            Diretório de Origem:
                        </td>
                        <td>
                            <asp:TextBox ID="txtOrigem" runat="server" Columns="60"></asp:TextBox>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            Diretório de Destino:
                        </td>
                        <td>
                            <asp:TextBox ID="txtDestino" runat="server" Columns="60"></asp:TextBox>
                        </td>
                    </tr>
                    <tr>
                        <td colspan="2">
                            <asp:Button runat="server" ID="btnGerar" Text="Gerar Zip do Diretório inteiro" />
                            <asp:Label runat="server" ID="lblErro" Font-Bold="true" ForeColor="red"></asp:Label>
                        </td>
                    </tr>
                </table>
            </fieldset>
            <br />   <br />
            <fieldset>
                <legend>Criar Arquivo Zip de um único Arquivo </legend>
                <table style="border: none;">
                    <tr>
                        <td>
                            Arquivo para ser "zipado":
                        </td>
                        <td>
                            <asp:TextBox ID="txtArquivoOrigem" runat="server" Columns="60"></asp:TextBox>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            Diretório de Destino:
                        </td>
                        <td>
                            <asp:TextBox ID="txtArquivoDestino" runat="server" Columns="60"></asp:TextBox>
                        </td>
                    </tr>
                    <tr>
                        <td colspan="2">
                            <asp:Button runat="server" ID="btnGerarArquivo" Text="Gerar Zip de um único Arquivo" />
                            <asp:Label runat="server" ID="lblErroArquivo" Font-Bold="true" ForeColor="red"></asp:Label>
                        </td>
                    </tr>
                </table>
            </fieldset>
        </div>
        <br />   <br />
        <fieldset>
            <legend>Descompactar Arquivo .ZIP </legend>
            <table style="border: none;">
                <tr>
                    <td>
                        Arquivo para ser "deszipado":
                    </td>
                    <td>
                        <asp:TextBox ID="txtArquivoParaDescompactar" runat="server" Columns="60"></asp:TextBox>
                    </td>
                </tr>
                <tr>
                    <td>
                        Diretório para arquivos serem descompactados :
                    </td>
                    <td>
                        <asp:TextBox ID="txtDescompactarArquivos" runat="server" Columns="60"></asp:TextBox>
                    </td>
                </tr>
                <tr>
                <td colspan="2">
                <asp:Button runat="server" ID="btnDescompactar" Text="Descompactar arquivo zip" />
                <asp:Label ID="lblErroDescompactar" runat="server" Font-Bold="true" ForeColor="red"></asp:Label>
                </td>
                </tr>
            </table>
        </fieldset>
    </form>
</body>
</html>

Inicialização da Página


    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        If Not Page.IsPostBack Then
            ' Aqui eu dou um valor inicial, só para te ajudar a começar com um teste
            txtDestino.Text = Server.MapPath("") & "\Destino\"
            txtOrigem.Text = Server.MapPath("") & "\Origem\"

            ' Arquivo
            txtArquivoDestino.Text = Server.MapPath("") & "\Destino\"
            txtArquivoOrigem.Text = Server.MapPath("") & "\Origem\Figura.jpg"

            ' Descompactar
            txtDescompactarArquivos.Text = Server.MapPath("") & "\Descompactar\"
            subInitDescompactarArquivos()
        End If

    End Sub

    ''' <summary>
    ''' Sub só para demonstação, para você poder dezipar um arquivo, depois de enviá-lo
    ''' </summary>
    ''' <remarks></remarks>
    Protected Sub subInitDescompactarArquivos()
        Dim sArquivos As String()
        Dim sArquivo As String

        ' Seleciono todos os arquivos do tipo zip.
        sArquivos = Directory.GetFiles(txtArquivoDestino.Text, "*.zip")

        For Each sArquivo In sArquivos
            txtArquivoParaDescompactar.Text = sArquivo
            Exit For
        Next

    End Sub

Considerações finais

É possível também trabalhar com arquivos .tar, Gzip e BZip2 de forma análoga.

Fonte: Imasters

Próxima Página »

SEO Powered by Platinum SEO from Techblissonline