Uma a cada cinco empresas nos EUA usa o Google Docs, diz IDC
A larga dominância do pacote de aplicativos de produtividade Microsoft Office nas empresas pode estar perto de enfrentar um grande desafio: o Google Docs.
Um estudo da consultoria IDC apontou que o software online de produtividade do Google é “amplamente” usado em uma a cada cinco companhias, mesmo que, em alguma delas, o pacote seja apenas um complemento ao Office.
O IDC entrevistou 262 gerentes de nível sênior de empresas de diferentes tamanhos, o que aponta para um rápido crescimento no interesse pelo serviço.
Uma pesquisa similar, feita em dezembro de 2007, apontava que 5% das empresas entrevistadas usavam amplamente o Google Docs na época. Na atual pesquisa, feita em julho, o Google Docs é usado em 19,5% das companhias.
“O Google Docs ainda não está substituindo o Office, mas o fato de ele crescer tão rapidamente mostra um momento importante. É uma grande ameaça à Microsoft”, disse a analista do IDC, Melissa Webster.
Apesar do crescimento do Google Docs, o uso do Office praticamente não mudou entre as duas pesquisas, com mais de 97% de uso nas companhias – indicativo de que os funcionários usam ambas as ferramentas.
Para Melissa, isso é negativo para a dona do Office, porque o Google Docs “vai canibalizar a oportunidade da Microsoft em torno de seus próprios softwares baseados na web”, disse ela.
Na quinta-feira (17/9), a companhia começou a testar o Office Web Apps, a versão online do pacote de aplicativos, que ainda não tem data definida para lançamento.
Criando um Data Grid com POO e PHP5
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:
- Vamos ocultar o “ID” do array associativo, para que não seja mostrado.
- 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.
- 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
Entendendo um pouco a API Google Maps
O Google dispensa comentários com todas as inovações que ele faz. Hoje falaremos um pouco sobre a API do Google Maps. API (Application Programming Interface ou Interface de Programação de Aplicativos) é a forma que temos de nos comunicar com as funções pré-programadas definidas pelo fornecedor, no caso, Google. Esta API permite a criação de mapas com locais definidos, controle de zoom, tipos de mapa, geração de rotas, pesquisa por estabelecimentos, e muitas coisas mais.
Como começar
A primeira coisa que devemos fazer é acessar o link da página inicial da API, ler e aceitar o contrato, digitar a url do site que deseja usar a API e clicar no botão “Gerar chave da API”. (veja a figura 1)

Figura 1: Aceitando o contrato
Após isso, caso ainda não esteja logado com a sua “Google Account”, o Google pedirá para efetuar o login, nesse passo você obterá a chave para usar a API somente na url que digitou o site. Caso queira usar a API em outro site, deverá repetir esse processo para cada site que quiser. (Veja a figura 2)

Figura 2: Chave gerada
Agora que já temos a chave, podemos usar a API no site. O Google disponibiliza alguns exemplos, para trabalhar com JavaScript, Flash, Serviço, etc..
Neste artigo abordaremos o uso da API para JavaScript e para isso devemos adicionar o seguinte script dentro do bloco head do HTML, no local “SUA_CHAVE”, você deve colocar a chave que o Google gerou para o site, veja o campo Your key is na figura 2.
<script src="http://maps.google.com/maps?file=api&v=2&sensor=true&key=SUA_CHAVE" type="text/javascript">
</script>
O código de base para começar o aprendizado está abaixo:
<!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">
<head>
<title>Aprendendo a Usar a API Google Maps | Paulo Fernandes </title>
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"/>
<script src="http://maps.google.com/maps?file=api&v=2&sensor=true&
key=ABQIAAAAAaVFxs6kNq7gWY59qf5XMxSec6s_uUscdbTyPSy8oWl8zYzqFRRanjFebOU60thMmEQQDEPx3A3y5Q"
type="text/javascript"></script>
<script type="text/javascript">
var map = null;
var geocoder = null;
function inicializa() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("mapa_base"));
map.setCenter(new GLatLng(-22.9035393, -43.2095869), 13);
geocoder = new GClientGeocoder();
}
}
</script>
</head>
<body onload="inicializa()" onunload="GUnload()">
<div id="mapa_base" style="width: 500px; height: 300px"></div>
</body>
</html>
Este código não está difícil de entender, explicaremos as partes mais importantes:
- No onload(), a função inicializa() verifica se o navegador do usuário é compatível com a API Google Maps, caso positivo, o método captura uma div com id igual a “mapa_base” e define o mapa centralizado. O local padrão que escolhi foi a cidade do Rio de Janeiro, que é representada pelas seguintes coordenadas de latitude e longitude -22.9035393, -43.2095869, respectivamente. O número seguinte, 13, representa o zoom no mapa, quanto menor esse número, menor o zoom.
- No onunload(), a função GUnload() serve para limpar as estruturas internas e liberar a memória.
Para mais informações sobre os métodos, acesse a documentação em português, através deste link. Essa documentação está interessante, e será a base para o artigo.
Exemplos simples
Neste link podemos analisar diversos exemplos do poder desta API.
Para o artigo, colocaremos alguns exemplos interessantes para inserir um mapa personalizado no site.
- Descobrir qual a latitude e longitude do endereço: Isso é útil quando se pretende definir algum local como default ao entrar no site. Para isso faremos um formulário onde você digita o endereço e o mapa é carregado no endereço e exibe o posicionamento de latitude e longitude. O código JavaScript é esse:
function mostraEndereco(){
var endereco = document.getElementById("endereco").value;
if ( geocoder ) {
geocoder.getLatLng(endereco,
function(point){
if ( !point ) {
alert(endereco + " não encontrado");
} else {
map.setCenter(point, 13);
var marca = new GMarker(point);
map.addOverlay(marca);
marca.openInfoWindowHtml( endereco + "<br />" + point.toString() );
}
}
);
} else {
alert("GeoCoder não identificado");
}
}
E no HTML:
<form id="form_mapa" action="#" method="get">
<input type="text" name="endereco" id="endereco" size="50" value="São Paulo" />
<input type="button" name="enviar" id="enviar" value="Mostrar Latitude/Longitude" onclick="mostraEndereco()"/>
</form>
- Definindo um evento: Para definir um evento precisamos utilizar o objeto GEvent. Seguindo a mesma linha do código, definiremos um evento, que será disparado toda vez que o marcador for clicado, fazendo com que a posição geográfica seja exibida. Devemos colocar esse evento na função mostrarEndereco(), pois é nela que definimos o marcador.
GEvent.addListener(marca, "click", function() {
marca.openInfoWindowHtml( endereco + "<br />" + point.toString() );
});
- Adicionando zoom no mapa: Para adicionar o controle de zoom, devemos adicionar um controle ao mapa, através do método addControl() e a esse controle devemos adicionar o controle do mapa, o mais correto é adicionar isso na função de inicialização: inicializa(), a linha completa que deve ser inserida é esta:
map.addControl( new GSmallMapControl() );
- Adicionando forma de visualização: Podemos definir um controle para que o usuário possa ver o endereço na forma de mapa, híbrido ou satélite. Para isso devemos seguir a mesma linha de raciocínio para inserir o zoom, que seria adicionar um controle.
map.addControl( new GMapTypeControl() );
Exemplo avançado
Para mostrar algo avançado, que tal traçar a rota do ponto A ao ponto B? Para isso precisaremos que o usuário digite os valores dos pontos A e B. Para traçar a rota, vamos reescrever todo o exemplo, simplificando as configurações.
<!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">
<head>
<title>Aprendendo a Usar a API Google Maps - Obter Rota | Paulo Fernandes </title>
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"/>
<script
src="http://maps.google.com/maps?file=api&v=2&sensor=true&
key=ABQIAAAAAaVFxs6kNq7gWY59qf5XMxSec6s_uUscdbTyPSy8oWl8zYzqFRRanjFebOU60thMmEQQDEPx3A3y5Q"
type="text/javascript"></script>
<script type="text/javascript">
var map = null;
var geocoder = null;
var from;
var to;
var directionsPanel = null;
var directions = null;
function inicializa() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("mapa_base"));
map.setCenter(new GLatLng(-22.5489433, -46.6388182), 7);
geocoder = new GClientGeocoder();
map.addControl( new GSmallMapControl() );
map.addControl( new GMapTypeControl() );
directionsPanel = document.getElementById("route");
directions = new GDirections(map, directionsPanel);
}
}
function gerarRota(){
from = document.getElementById("partida").value;
to = document.getElementById("destino").value;
if ( geocoder ) {
geocoder.getLatLng(from,
function(point){
if ( !point ) {
alert(from + " não encontrado");
}
}
);
geocoder.getLatLng(to,
function(point){
if ( !point ) {
alert(to + " não encontrado");
}
}
);
var string = "from: " + from + " to: "+to;
directions.clear();
directions.load(string);
GEvent.addListener(directions, "error", erroGetRoute);
} else {
alert("GeoCoder não identificado");
}
}
function erroGetRoute(){
alert("Não foi possivel traçar a rota de: " + from + " para: " + to );
}
</script>
</head>
<body onload="inicializa()" onunload="GUnload()">
<form id="form_mapa" action="#" method="get">
<label for="partida">Partida</label>
<input type="text" name="partida" id="partida" value="São Paulo" size="50" />
<br />
<label for="destino">Destino</label>
<input type="text" name="destino" id="destino" value="Rio de Janeiro" size="50" />
<br />
<input type="button" name="enviar" id="enviar" value="Obter Rota" onclick="gerarRota()"/>
</form>
<div id="mapa_base" style="width: 800px; height: 500px;"></div>
<div id="route" style="width: 300px; height: 500px; position: absolute; right: 0; top: 0;"></div>
</body>
</html>
Para mostrar a rota, tivemos que criar uma nova div com o id igual à “route”, é neste local que exibiremos o passo a passo da rota traçada. Essa captura do local foi feita nesta linha directionsPanel = document.getElementById(“route”); Para traçar a rota, devemos instanciar o objeto GDirections e informar para ele carregar a rota através do método directions.load(string);
No método load devemos passar os dois endereços escritos por extenso, antes o endereço de partida devemos atribuir from: e antes do endereço de destino to: , ficando a string completa from: São Paulo to: Rio de Janeiro, por exemplo.
Caso algum dos dois endereços não seja encontrado, o código exibirá um alert informando que a rota não pode ser traçada.
Conclusão
Com este artigo pudemos perceber o poder que a API nos dá, ela nos fornece outras diversas possibilidades que podem ser vistas na documentação oficial. O objetivo do artigo foi introduzir os principais conceitos e o que se pode utilizar no site de sua empresa, por exemplo.
Algo que devemos tomar cuidado é na declaração das variáveis, pois o local onde ela é declarada pode fazer com que a API se porte de forma indesejada. Por exemplo, quando declaramos uma marca, se a tivemos declarado fora da função a cada novo endereço, a marca anterior seria perdida, mas repare que a informação de latitude e longitude é perdida, mantendo somente a ultima. Faça o teste, declare a variável fora do método, acredito que achará bem interessante.
Pode ser que exista outra forma de fazer o que demonstramos ou até que o que foi demonstrado esteja errado, mesmo que aparentemente funcionando.
Fonte: Imasters
Frameworks no PHP: O que, quando, por que e qual?
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
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.
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
Manipulação de dados BLOB com PHP e MySQL
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
Barra de Progresso com AJAX
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
Construindo aplicações ricas de internet com Adobe Flex 3 e ASP.NET
Utilizarei o Visual Studio 2008 com o SQL Server 2005 e o banco de dados Northwind, porém os mesmos passos podem ser seguidos no Visual Studio 2005 com o SQL Server 2000.
Crie um novo projeto Web no Visual Studio, logo em seguida clique com o botão direito sobre a solução e escolha Add / New Item.

Na janela que se abrirá, selecione o Item DataSet e atribua o nome DsTerritorio.

Com o DataSet criado, clique com o botão direito dentro da janela do DataSet, escolha Add / TableAdapter, abrirá uma janela solicitando qual conexão com o banco de dados será utilizado para a construção do TableAdapter, crie a conexão com o SQL Server e salve com o nome NorthwindConn e clique em Next.


Na próxima janela selecione como o TableAdapter acessará o banco de dados, as opções possíveis são: SQL statements, criar nova Stored Procedure ou utilizar uma Stored Procedure já existente no banco de dados.
Deixe a opção Use SQL statements marcada e clique em Next.

A próxima janela é onde se insere o código SQL para o retorno dos dados, porém você pode utilizar o Query Builder, que é a ferramenta visual para construção de instruções SQL, portanto clique no botão Query Builder.

Após clicar no botão Query Builder, aparecerão duas janelas, a janela do próprio Query Builder e a janela de Add Table, a segunda janela já com as tabelas existentes no banco de dados.
Procure e selecione a tabela Region, em seguida, clique em Add. A tabela Region aparecerá no Query Builder.

Clique em Close, em seguida, selecione as duas colunas da tabela Region (RegionID e RegionDescription). Agora clique em Execute Query.

Se o resultado do Execute Query for igual à figura acima, clique em Ok. A próxima janela solicitará nomes para os métodos de Fill e Return que por padrão são Fill e GetData respectivamente.
Para a tabela Region, deixe os nomes sugeridos e clique em Next. A próxima janela exibirá o sumário da criação do TableAdapter. Clique em Finish.


Agora já é possível visualizar o TableAdapter dentro do DataSet dsTerritorio.

Ainda dentro do DataSet dsTerritorio, crie outro TableAdapter. Novamente, clique com o botão direito dentro do DataSet, escolha Add / TableAdapter, escolha a conexão com a base de dados, também escolha Use SQL statements.
Na janela do Query Builder, adicione a tabela Territories, selecione todas as colunas. Na linha RegionID, insira o parâmetro @RegionID na coluna Filter. O parâmetro será responsável por aplicar o filtro de qual região o SQL retornará os territórios.

Na janela de definições dos métodos, acrescente a expressão ByRegionID, após Fill e GetData. Dessa maneira apenas pelo nome do método é possível saber que um parâmetro chamado RegionID é esperado.


Agora que concluiu a criação do DataSet dsTerritorio, crie o DataSet dsVendedor, e dentro dele crie um TableAdapter com o SQL abaixo.
SELECT EmployeeTerritories.EmployeeID,
Employees.FirstName + ' ' + Employees.LastName AS FullName,
EmployeeTerritories.TerritoryID
FROM Employees INNER JOIN EmployeeTerritories
ON Employees.EmployeeID = EmployeeTerritories.EmployeeID
WHERE (EmployeeTerritories.TerritoryID = @TerritoryID)

Acrescente ByTerritoryID na definição dos métodos Fill e GetData.
Após clicar em Finish, o TableAdapter criado estará com os nomes DataTable1 e DataTable1TableAdapter, altere-os para Employee e EmployeeTableAdapter.

Crie um novo DataSet chamado dsCliente, e também crie um novo TableAdapter com o código abaixo.
SELECT Customers.CustomerID, Customers.CompanyName, CustomerEmployee.EmployeeID
FROM (SELECT CustomerID, EmployeeID
FROM Orders
GROUP BY CustomerID, EmployeeID) AS CustomerEmployee INNER JOIN
Customers ON CustomerEmployee.CustomerID = Customers.CustomerID
WHERE (CustomerEmployee.EmployeeID = @EmployeeID)
Para os nomes dos métodos Fill e GetDate, não esqueça de adicionar ByEmployeeID em ambos.
Como no TableAdapter de vendedores, os nomes deste TableAdapter também não estão corretos, altere-os para Customers e CustomersTableAdapter respectivamente.
Para concluir a construção dos DataSets, crie mais um chamado dsPedido e também crie um novo TableAdapter com o código abaixo.
SELECT OrderID, CustomerIR, EmployeeID, OrderDate, ShippedDate,
ShipName, ShipAddress, ShipCity, Shipcountry
FROM Orders
WHERE (CustormerID = @CustomerID) AND
(EmployeeID = @EmployeeID)
Acrescente ByCustomerIDEmployeeID aos métodos Fill e GetData e clique em Finalizar.
Agora crie o último TableAdapter chamado OrderDetails conforme a figura abaixo.

Após a criação de todos os DataSets (Território, Vendedor, Cliente e Pedido) o projeto deve estar conforme a figura abaixo.

Copie os seguintes arquivos do diretório de instalação do WebOrb (por padrão em c:\inetpub\wwwroot\weborb30) para o diretório do projeto .NET.
/weborb.config
/bin/weborb.dll
/WEB-INF
Adicione o código XML abaixo ao web.config do projeto .NET.
<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="weborb.aspx" type="Weborb.ORBHttpHandler"/>
<add verb="*" path="codegen.aspx" type= "Weborb.Management.CodeGen.CodegeneratorHttpHandler"/>
</httpHandlers>
</system.web>
</configuration>
É preciso referenciar o weborb.dll ao projeto, para isso no Solution Explorer do Visual Studio, clique duas vezes sobre a opção My Project, em seguida clique em References e depois em Add / References?

Clique na aba Browse, localize o diretório Bin do projeto, selecione o arquivo weborb.dll e clique em OK, salve o projeto e feche a janela My Project.

Clique com o botão direito sobre a solução e escolha Add / New Item, porém escolha Class e dê o nome de csFlex.vb.
Nesta classe serão criados os métodos de chamada e retorno dos DataSets e TableAdapters criados anteriormente, através desses métodos é que a comunicação entre o .NET e o Flex ocorrerá.
Insira o código abaixo ao arquivo csFlex.vb
Imports Weborb.Service
Public Class csFlex
Public Function getRegion() As DataTable
Return New dsTerritorioTableAdapters.RegionTableAdapter().GetData()
End Function
Public Function getTerritories(ByVal RegionID As String) As DataTable
Return New dsTerritorioTableAdapters.TerritoriesTableAdapter().GetDataByRegionID(RegionID)
End Function
Public Function getEmployee(ByVal TerritoryID As String) As DataTable
Return New dsVendedorTableAdapters.EmployeeTableAdapter().GetDataByTerritoryID(TerritoryID
End Function
Public Function getCustomers(ByVal EmployeeID As String) As DataTable
Return New dsClienteTableAdapters.CustomersTableAdapter().GetDataByEmployeeID(EmployeeID)
End Function
Public Function getOrders(ByVal CustomerID As String, ByVal EmployeeID As String) As DataTable
Return New dsPedidoTableAdapters.OrdersTableAdapter().GetDataByCustomerIDEmployeeID(CustomerID, EmployeeID)
End Function
Public Function getOrderDetails(ByVal OrderID As String) As DataTable
Return New dsPedidoTableAdapters.OrderDetailsTableAdapter().GetDataByOrderID(OrderID)
End Function
End Class
Salve e feche o arquivo csFlex, agora compile o projeto. Caso o Visual Studio sinalize algum erro, volte e execute os passos novamente.
Antes de criar a interface no Adobe Flex, crie a aplicação Web no Internet Information Services (IIS) com o nome do projeto, verifique se ao acessar o endereço através do navegador uma página em branco é exibida.
Agora já com a aplicação web configurada no IIS, abra o Adobe Flex Builder 3, adicione um novo projeto (File / New / Flex Project).
Agora defina o nome do Projeto, se a opção Use default location estiver marcada, desmarque-a e localize o endereço do projeto .NET e dentro da pasta do projeto crie uma nova pasta chamada FlexSrc. O Project location do Flex deve ficar como a figura abaixo. A opção de Application type deixe marcado Web Application, e em Server technology selecione ASP.NET. Clique em Next.

Na próxima janela, na opção Server selecione Use Internet Information Services (IIS), em Web application root informe o diretório raiz da aplicação web definida no IIS e no campo Web application URL informe o endereço da aplicação no IIS. Após clicar no botão Validate Configuration, na parte superior da janela o Flex Builder deve ser informar: “The web application root and URL are valid”, caso apareça outra mensagem, os endereços informados não estão corretos, corrija antes de prosseguir.
Na mesma janela, um pouco abaixo está definida a pasta bin-debug como local a serem salvos os arquivos Flex compilados, deixe o nome que o Builder sugeriu e clique Next.

Na última janela de configuração do projeto Flex, é possível definir qual a pasta onde o Flex Builder salvará os arquivos fontes, bem como qual o nome do primeiro arquivo do projeto a ser criado.
Deixe os campos preenchidos como o Builder sugeriu e clique em Finish. Após alguns segundos o Adobe Flex Builder 3 exibirá o arquivo ArtigoFlex.mxml pronto para o início da construção da interface da aplicação.

Porém antes começar a codificar é necessário incluir um argumento de compilação ao projeto, pois sem esse argumento o Flex não conseguirá acessar os métodos construídos na classe csFlex. Para incluir o argumento, clique com o botão direito sobre o nome do projeto no Flex Navigator e em seguida clique em Properties. Com a janela de propriedades aberta, clique sobre a opção Flex Compiler, e insira o argumento após o argumento ?locale en_US
-services c:\Inetpub\wwwroot\weborb30\web-inf\flex\services-config.xml

Após inserir o argumento services, clique em OK.
Agora com o projeto corretamente configurado e pronto para comunicar com o .NET é possível iniciar a construção da interface, para tanto crie um painel, entre as tags , com o título Painel de Vendas, esse painel terá um tamanho ajustável conforme as dimensões do navegador do cliente, para isso configure as propriedades left, right, top e bottom, todos com o valor 10.
<mx:Panel layout="absolute" left="10" right="10" top="10" bottom="10" title="Painel de Vendas">
</mx:Panel>
É possível verificar como o projeto está ficando, bastar clicar no Play.

Dentro do painel, crie um canvas na cor cinza.
<mx:Canvas height="42" left="0" top="0" right="0" backgroundColor="#F3F3F3" borderStyle="none" borderThickness="1" borderColor="#C2BEBE">
</mx:Canvas>
Dentro do canvas coloque os labels e comboboxs que serão utilizados para selecionar região, território, vendedor e cliente, coloque também dentro do canvas o botão consultar.
<mx:Label y="12" text="Região" horizontalCenter="-348"/>
<mx:ComboBox y="10" id="cbRegion" labelField="RegionDescription" width="89" horizontalCenter="-274"></mx:ComboBox>
<mx:Label y="12" text="Território" horizontalCenter="-194"/>
<mx:ComboBox y="10" id="cbTerritory" labelField="TerritoryDescription" width="89" horizontalCenter="-114"></mx:ComboBox>
<mx:Label y="12" text="Vendedor" horizontalCenter="-32"/>
<mx:ComboBox y="10" id="cbEmployee" labelField="FullName" width="89" horizontalCenter="49"></mx:ComboBox>
<mx:Label y="12" text="Cliente" horizontalCenter="124"/>
<mx:ComboBox y="10" id="cbCustomer" labelField="CompanyName" width="89" horizontalCenter="198"></mx:ComboBox>
<mx:Button y="10" label="Consultar" width="119" horizontalCenter="310" id="btConsultar"/>
A propriedade horizontalCenter define qual a distância em pixel que um objeto está do centro da página, valores negativos representam objetos a esquerda do centro da tela e valores positivos representam objetos a direita, os valores definidos garantem que os objetos estarão sempre centralizados.
labelField é a propriedade que define qual o campo que será exibido como label do combobox. O Adobe Flex trabalha de maneira diferente do .NET quando o assunto é combobox ou dropdownlist, pois no .NET é possível definir apenas dois valores ao dropdownlist, o datatextfield e o datavalueFfeld, já no Adobe Flex só se define qual será o valor de exibição do combobox, labelField, pois cada linha de opção do combobox é um objeto com propriedades. Essas propriedades são as colunas que retornaram do banco de dados, logo você não tem acesso a somente duas colunas como dropdownlist, você tem acesso a todas as colunas que retornaram do banco de dados.
A propriedade Y define qual a distância que o objeto tem do topo do componente ao qual ele está pertencendo, neste caso, y=”12″ diz ao Flex que o label está a 12 pixel do topo do canvas.
Após o canvas inclua um datagrid onde serão exibidos os pedidos resultantes da consulta ao banco de dados.
<mx:DataGrid id="dgPedido" right="10" left="10" top="55" bottom="10">
<mx:columns>
<mx:DataGridColumn headerText="Detalhes" width="85"/>
<mx:DataGridColumn headerText="Data Pedido" dataField="OrderDate"/>
<mx:DataGridColumn headerText="Data Entrega" dataField="ShippedDate"/>
<mx:DataGridColumn headerText="Entregue para" dataField="ShipName"/>
<mx:DataGridColumn headerText="Endereço" dataField="ShipAdress"/>
<mx:DataGridColumn headerText="Cidade" dataField="ShipCity"/>
<mx:DataGridColumn headerText="País" dataField="ShipCountry"/>
</mx:columns>
</mx:DataGrid>
Para fazer a comunicação entre a interface Flex e a aplicação server-side .NET utilize o componente RemoteObject do Adobe Flex 3.
<mx:RemoteObject id="roNet" destination="GenericDestination"
source="ArtigoFlex.csFlex" showBusyCursor="true"
fault="faultHandler(event)" >
<mx:method name="getRegion" result="gotRegion(event)" />
<mx:method name="getTerritories" result="gotTerritories(event)" />
<mx:method name="getEmployee" result="gotEmployee(event)" />
<mx:method name="getCustomers" result="gotCustomers(event)" />
<mx:method name="getOrders" result="gotOrders(event)" />
<mx:method name="getOrderDetails" result="gotOrderDetails(event)" />
</mx:RemoteObject>
A propriedade destination deve sempre ser “GenericDestination” para a comunicação através do weborb, a propriedade source deve ser preenchida com o nome do projeto .NET e a classe que será acessada, então neste caso será “ArtigoFlex.csFlex”.
A propriedade showBusyCursor seta se será exibido ou não o relógio como cursor do mouse enquanto alguma requisição ao .NET estiver sendo feita. E finalmente, fault define qual função será disparada caso algum erro ocorra durante alguma requisição do .NET.
Os métodos (
A propriedade result define qual função será disparada após o retorno da requisição ao .NET.
É necessário agora construir as funções, faultHandler, gotRegion, gotTerritories, gotEmployee, gotCustomers, gotOrders e gotOrderDetails. As funções são escritas na linguagem Action Script 3.0
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
]]>
</mx:Script>
Nesta parte do código além do bloco das tags de inicio e fim de script, também estão declaradas as importações das bibliotecas ResultEvent, Alert e FaultEvent que serão utilizadas logo mais.
Agora crie a função faultHandler
private function faultHandler(event:FaultEvent):void
{
Alert.show(event.fault.faultString, "Erro");
}
A função faultHandler recebe um parâmetro do tipo FaultEvent que será exibido para o usuário através do Alert.show quando algum erro ocorrer durante a requisição ao .NET.
Agora crie os métodos de preenchimento dos valores do combobox região.
private function bindRegion():void
{
roNet.getRegion();
}
private function gotRegion(event:ResultEvent):void
{
cbRegion.dataProvider = event.result;
cbRegion.selectedIndex = 0;
bindTerritories();
}
No código acima foram criadas duas funções, bindRegion e gotRegion. A função bindRegion chama o método getRegion do remote object roNet.
Após o retorno da requisição ao método roNet.getRegion, a função gotRegion é disparada recebendo um parâmetro do tipo ResultEvent que contém o retorno do método getRegion, o retorno é associado como dataProvider do combobox cbRegion, em seguida é selecionado o índice zero dos dados retornados. Após a seleção do índice, a função bindTerritories() é disparada.
private function bindTerritories():void
{
roNet.getTerritories(cbRegion.selectedItem.RegionID);
}
private function gotTerritories(event:ResultEvent):void
{
cbTerritory.dataProvider = event.result;
cbTerritory.selectedIndex = 0;
bindEmployee();
}
Assim como a função bindRegion, bindTerritories chama um método do remote object roNet, porém agora o método chamado é o getTerritories, esse método espera como parâmetro o código da região, por isso o parâmetro informado é o cbRegion.selectedItem.RegionID. RegionID é uma propriedade que o dataProvider do cbRegion passou a ter após a atribuição do event.result. Abaixo estão as demais funções para a preparação dos comboboxs.
private function bindEmployee():void
{
roNet.getEmployee(cbTerritory.selectedItem.TerritoryID);
}
private function gotEmployee(event:ResultEvent):void
{
cbEmployee.dataProvider = event.result;
cbEmployee.selectedIndex = 0;
bindCustomers();
}
private function bindCustomers():void
{
roNet.getCustomers(cbEmployee.selectedItem.EmployeeID);
}
private function gotCustomers(event:ResultEvent):void
{
cbCustomer.dataProvider = event.result;
cbCustomer.selectedIndex = 0;
}
Para que quando o usuário acesse a aplicação os comboboxs já sejam preenchidos é necessário definir a propriedade creationComplete na tag mx:Application.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="bindRegion()">
Com essa propriedade definida, depois de criada a aplicação, a função bindRegion será disparada iniciando assim a população de todos os comboboxs, pois eles estão aninhados.
Também é preciso configurar os comboboxs para que depois de alterada a seleção de um dos filtros, os outros sejam alterados também, para isso será utilizada a propriedade change.
<mx:ComboBox y="10" id="cbRegion" labelField="RegionDescription" width="89" change="bindTerritories()" horizontalCenter="-274"></mx:ComboBox>
<mx:ComboBox y="10" id="cbTerritory" labelField="TerritoryDescription" width="89" change="bindEmployee()" horizontalCenter="-114"></mx:ComboBox>
<mx:ComboBox y="10" id="cbEmployee" labelField="FullName" width="89" change="bindCustomers()" horizontalCenter="49"></mx:ComboBox>
Agora faça a população da datagrid,
private function bindOrders():void
{
roNet.getOrders(cbCustomer.selectedItem.CustomerID,cbEmployee.selectedItem.EmployeeID);
}
private function gotOrders(event:ResultEvent):void
{
dgPedido.dataProvider = event.result;
}
Para que a função bindOrders seja disparada ao clicar o botão Consultar, defina a propriedade click do botão btConsultar.
<mx:Button y="10" label="Consultar" width="119" click="bindOrders()" horizontalCenter="310" id="btConsultar"/>
Para finalizar o projeto, crie a estrutura para exibir os detalhes dos pedidos. Para isso crie uma TitleWindow, em File / New / MXML Component, defina o nome de orderDetails, baseado em TitleWindow

Utilize o código abaixo para a TitleWindow orderDetails.
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="730" height="420" title="Detalhes do Pedido" showCloseButton="true" close="{PopUpManager.removePopUp(this)}">
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import mx.events.CloseEvent;
]]>
</mx:Script>
<mx:DataGrid left="10" right="10" top="10" bottom="10" id="dgOrderDetails">
<mx:columns>
<mx:DataGridColumn headerText="Cód." dataField="ProductID"/>
<mx:DataGridColumn headerText="Produto" dataField="ProductName"/>
<mx:DataGridColumn headerText="Preço Un." dataField="UnitPrice"/>
<mx:DataGridColumn headerText="Qtde" dataField="Quantity"/>
<mx:DataGridColumn headerText="Desconto" dataField="Discount"/>
<mx:DataGridColumn headerText="Total" dataField="Total"/>
</mx:columns>
</mx:DataGrid>
</mx:TitleWindow>
Crie as funções para a população da TitleWindow orderDetails dentro do script do arquivo ArtigoFlex.mxml
import mx.managers.PopUpManager;
public function bindOrderDetails():void
{
roNet.getOrderDetails(dgPedido.selectedItem.OrderID);
}
private function gotOrderDetails(event:ResultEvent):void
{
var popUp:orderDetails = orderDetails(PopUpManager.createPopUp(this, orderDetails, true));
PopUpManager.centerPopUp(popUp);
popUp.dgOrderDetails.dataProvider = event.result;
}
Altere a primeira coluna da datagrid dgPedido para o código abaixo para inserir o botão para exibir os detalhes do pedido.
<mx:DataGridColumn headerText="Detalhes" width="85">
<mx:itemRenderer>
<mx:Component>
<mx:HBox width="100%" height="100%" horizontalAlign="center">
<mx:Button y="10" width="80" label="Detalhes" click="outerDocument.bindOrderDetails()" id="btDetalhes"/>
</mx:HBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
Salve o projeto e execute, o resultado deve ser como o das figuras abaixo.


Baixe o código fonte completo.
Divirta-se.
Publicado originalmente em http://www.igormusardo.com.br
Fonte: Imasters
Consultar bolsa de valores por PHP
No exemplo desse artigo vamos usar um ativo da Petrobrás (PETR4, essa é a sigla) e para lermos o XML vamos usar simple_xml.
Então o que precisamos saber para consultar os índices de um ativo na bolsa?
- A sigla de um ativo – PETR4
Veja abaixo um código exemplo:
<?php
$url_base = "http://www.theoziran.org/webservice/bovespa/";
$indice = "petr4";
$url_xml = $url_base.$indice;
$xml_string = file_get_contents($url_xml);
$simple_xml = simplexml_load_string($xml_string);
//O ativo consultado
$simple_xml->ativo;
//A cotação do dia
$simple_xml->dia;
//A cotação da semana
$simple_xml->semana;
//A cotação dos últimos sete dias
$simple_xml->setedias;
//A cotação do mês
$simple_xml->mes;
//A cotação dos últimos trinta dias
$simple_xml->trintadias;
//A cotação do ano
$simple_xml->ano;
//A contação dos últimos 365 dias
$simple_xml->ano-relativo;
//Data em que os dados foram capturados
$simple_xml->data;
?>
HTML 5 – Mudanças na estrutura e semântica
A Semântica sempre é um dos pontos mais importantes do desenvolvimento com Padrões Web. Algumas iniciativas com o Microformats vieram na tentativa de trazer mais semântica ainda para nossos códigos, com o intuito de que novas aplicações e oportunidades pudessem utilizar melhor a informação distribuída na web. Acontece que o resto do HTML não foi há bastante tempo modificado. Por exemplo, como você consegue distinguir de forma automática as informações do “header” (cabeçalho) dos sites? Não consegue. Você não consegue, por exemplo, de maneira automatizada, identificar o que é um rodapé ou a parte do layout que está exibindo um artigo.
Todos os dias sites e mais sites são publicados na internet e nenhum deles com um padrão de nomenclatura de classes e ids que possamos utilizar para extrair informação de maneira inteligente. O HTML 4.01 é a versão atual da linguagem básica da Web, e não é atualizado há alguns anos. Esses detalhes de semântica não podem ser supridos para sempre por tecnologias como o Microformats. A versão 5 do HTML tende a suprimir essas necessidades e também atualizar pontos antigos do HTML 4, por exemplo, formulários.
Como disse no começo deste artigo, a estrutura de um site não é óbvia para as máquinas. Não existe nenhum padrão de construção dos elementos para indicar o que é o cabeçalho e o que é o rodapé, por exemplo. No HTML 5, iremos utilizar um padrão de tags que nos ajudará a marcar estas estruturas. Uma estrutura conhecida é mais ou menos assim:
<body>
<div id="header">...</div>
<div id="menu">...</div>
<div class="post">...</div>
<div id="sidebar">...</div>
<div id="rodape">...</div>
</div>
</body>
Na estrutura acima, utilizei alguns nomes de classes e ids que costumamos utilizar no dia-a-dia. Eu mesmo não utilizo a classe POST, uso mais CONTENT ou algo parecido. A estrutura do HTML acabará com isso. A idéia é substituir esse amontoado de DIVS por elementos que se encarreguem dessas funções, um exemplo da estrutura serial:
<body>
<header>...</header>
<nav>...</nav>
<article>
<section>
...
</section>
</article>
<aside>...</aside>
<footer>...</footer>
</body>
- O elemento header define o cabeçalho. Nav define o menu ou a navegação do site.
- Article define uma parte da página que tem uma composição de formulários, textos etc. Por exemplo, pode ser um post de forum, blog, comentários etc.
- O elemento Section define uma seção do layout em um determinado element. Ele pode conter um header e também um footer se preciso.
- O elemento aside consiste em envolver informações que tem algo a ver com o conteúdo principal do site. Pode ser um menu lateral, um sidebar padrão com menu, banner, busca etc…
- Footer define o rodapé do elemento ou do layout.
Entenda que, agora, qualquer elemento pode ter seu conteúdo separado por seções com o elemento section. Note também que os elementos podem ter também um header e um footer independentes do resto do layout. Como na imagem.

Uma dúvida comum entre os desenvolvedores é como fazer a estruturação e distribuição das tags de títulos (h1 até h6). Por exemplo, se eu utilizei já a tag H1 no logo do site, poderei utilizar para o título do artigo? Se repetirmos muitas vezes as mesmas tags de títulos, a importância que cada título tem sobre o outro se perderá. O Google poderá indexar de forma diferente e etc.
No HTML 5 esse problema ser resolverá, porque cada section que você inicia, você poderá começar novamente uma nova ordem de títulos. Por exemplo:
<header>
<h1>Logo</h1>
</header>
<article>
<section>
<h1>Título do artigo</h1>
<p>texto</p>
<h2>Subtitulo</h2>
<p>Mais texto</p>
</section>
</article>
Dessa forma você conseguirá definir exatamente qual a importância de cada título e os leitores de tela, sistemas de busca e outras aplicações conseguirão fazer uma separação mais eficaz dos elementos textuais.
Entenda que os divs não irão deixar de existir. Você os usará em casos muito específicos, por exemplo, para fazer caixas de destaque:
<section>
<div class="destaque">
<h1>Destaque 1</h1>
<p>Texto</p>
</div>
<div class="destaque">
<h1>Destaque 1</h1>
<p>Texto</p>
</div>
</section>
Para saber mais sobre isso, leia: The Elements Of HTML 5.
