Mostrando postagens com marcador PHP. Mostrar todas as postagens
Mostrando postagens com marcador PHP. Mostrar todas as postagens

quinta-feira, 20 de agosto de 2009

Dump com FirePHP/FireBUG e Zend Framework

Esses dias que eu estava me atualizando na internet, me deparei com um artigo falando sobre o FirePHP, que até aquele momento me era desconhecido.
Para todos os desenvolvedores que trabalham com Javascript em especialmente Ajax, o Firebug do Firefox é uma ferramenta "ferrada" para o debug e dump das informações que foram criadas via Javascript.

E que tal termos algo parecido só que para o PHP? Seria legal, não é verdade? É exatamente isso que o FirePHP faz.

Eu não falarei exatamente sobre o FirePHP, mas falarei sim sobre como utilizálo no Zend Framework por meio das classes já existentes no nosso maravilhoso framework que é uma mão na roda!

Quem quiser saber mais sobre o FirePHP, aconselho ler o mesmo artigo que li no imasters:
http://imasters.uol.com.br/artigo/13959/php/_como_debugar_aplicacoes_ajaxphp_com_firephp/

E também indico o manual do Zend que fala sobre o FirePHP:
http://framework.zend.com/manual/en/zend.log.writers.html#zend.log.writers.firebug

É por isso que gosto do Zend, pela sua vasta documentação :)


CRIANDO AS INSTÂNCIAS NECESSÁRIAS

O FirePHP funciona como um log. Do mesmo jeito que criamos log por meio da classe Zend_Log. É o Zend_Log quem delega o log atual registrado para os "log writers" e o Zend_Log_Writer_FireBug é um componente writer que envia o log para o FirePHP.

Em seu bootstrap, antes de você dar um dispatcher em seu controller, insira as linhas abaixo:

$logger = new Zend_Log();
$writer = new Zend_Log_Writer_Firebug();

//DIZ AO LOG QUEM É O WRITER, OU SEJA, QUEM IRÁ GRAVAR OS LOGS
$logger->addWriter($writer);

Para utilizar seu log em todo o seu projeto, você pode manter uma instancia do seu Logger para toda a aplicação e usar em suas views, controllers e models:
Zend_Registry::set('logger',$logger);

Utilizando o Logger:
$logger = Zend_Registry::get('logger');
$logger->log('Mensagem de log para o FirePHP!', Zend_Log::INFO);

Repare na constante INFO da classe Zend_Log.
Toda vez que chamarmos um Log, no FireBug do firefox será mostrada um ícone de informação com a mensagem do primeiro parametro.
Você também pode utilizar as constantes WARN ou ALERT como referência de log ou prioridade das mensagens.

Um exemplo disso, é utilizarmos esse log em blocos Try catch.
Exemplo:
try {
// Caso tenha ocorrido algum erro
} catch(Exception $e) {
Zend_Registry::get('logger')->err($e)
}

ou também de outra forma:

try {
// Caso tenha ocorrido algum erro
} catch(Exception $e) {
$logger->log('Erro em bloco try catch ao tentar inserir dados na Base: '.$e, Zend_Log::ALERT);
}


DUMP DE INFORMAÇÕES PROCESSADAS NA BASE DE DADOS

Seria legal nós termos um dump de todas as operações que são feitas em nossa base de dados, não acha?
Mas seria um saco, cansativo e de grande manutenabilidade termos que chamar nosso log toda hora.

Mas..olha só como o Zend é camarada...rs
No seu bootstrap mesmo, insira as seguintes linhas de código depois de ter setado o seu Adapter e antes do dispatcher do seu controller:

$profiler = new Zend_Db_Profiler_Firebug('All DB Queries');
$profiler->setEnabled(true);
//$db SERIA O SEU ADAPTER CONFIGURADO PARA ACESSAR A BASE DE DADOS.
$db->setProfiler($profiler);

Com esse código, toda vez que for enviada uma instrução SQL para nossa base, o FirePHP nos mostrará os dados enviados para o servidor, parecido com a imagem abaixo:


DICAS

Em meu firebug, eu tive que habilitar a opção Rede (Última aba da janela do FireBug).
Não esqueça de habilitar o seu FirePHP.
Insira seu site na lista de (allowed Sites) do FirePHP
Seria chato se os usuários que acessam o site visualizassem todos os dumps que usamos para nos basear em tempo de produção, não é verdade?
Para não enviarmos mais o dump, não é necessário tirar todas as linhas de código dos nossos objetos. Basta fazer o seguinte:

$writer->setEnabled(false);
$profiler->setEnabled(false);

Espero que tenham gostado da matéria e por favor, enviem sugestões, criticas ou elogios.
Abraços.

segunda-feira, 3 de agosto de 2009

Upload de arquivos com Zend Framework - Parte 2

Pessoal,
Criei uma classe que utiliza o Zend_File para o upload de arquivos.
Como sempre tive problemas ao postar códigos nesse blog, tive novamente que dar um printscreen da tela...

Eu criei uma classe abstrata chamada Utils, onde implemento todos os métodos que utilizo frequentemente em meu projeto.
Os métodos que crio nessa classe são estáticos, pq não precisarei criar uma estância deles cada vez que eu for utilizá-los.
Eu criei um diretório chamado "classes" dentro de application. Basta adicionar o include_path desse diretório em seu bootstrap.

Essa classe faz upload de todos os campos do tipo file que tiver na página.
@UploadDir: Diretório para onde será encaminhado o arquivo
@renameFile: Caso deseja renomear os arquivos para que não haja overwrite, deixe este parâmetro como true. Caso contrário, o arquivo sofrerá overwrite.
@allowedFiles: Caso filtrar os tipos de arquivos à enviar, crie um array contendo os formatos permitidos.



Reparem que eu utilizei um método da própria classe, que serve para identificar a extensão do arquivo.
Segue abaixo o código desse método estático:
static function findexts($filename)
{
$filename = strtolower($filename) ;

$exts = split("[/\\.]", $filename) ;

$n = count($exts)-1;

$exts = $exts[$n];

return $exts;
}


Para chamar a classe em Seus controllers:



Caso você queira permitir todos os tipos de arquivos, basta não passar o 3º parâmetro para a classe.

Caso o nome dos arquivos sejam renomeados, o nome inicial do arquivo será o nome do input, por exemplo: foto_perfil....jpg
Para verificar se houve erro no envio de algum arquivo, você pode fazer o seguinte tratamento:
//LOOP EM CIMA DOS ARQUIVOS ENVIADOS
foreach($filesUploaded as $fileUploaded)
{
//HOUVE ERRO NO ARQUIVO?
if(!strpos($fileUploaded, 'Erro:')) {...}
}


Qualquer dúvida, fiquem avontade de incluir comentários.


Instead of reinventing the wheel, I use Frameworks. ZEND FRAMEWORK! ;)

sexta-feira, 17 de julho de 2009

FUNÇÃO AJAX C/ JQUERY

E ai pessoal,
Tenho demorado para postar pq estou muuuuuito sem tempo :(

Está mais correria do que nunca, mas a vida honesta é dura, faz parte.

Eu comecei outro projeto nesse mes.
É um site de relacionamentos e terá muitas coisas em Ajax.
Eu pensei então em escrever uma função que me auxiliasse toda vez que fosse preciso carregar meus dados sem dar um Refresh na página inteira.
Essa função que eu desenvolvi é bem simples de utilizar.
Eu testei várias vezes e até agora tem suprido minhas necessidades.


As funções Javascript.

Infelizmente, o blog não me permite inserir códigos javascript. Então dei um printscreen da minha tela..e estou passando para vocês.

A PRIMERA FUNÇÃO QUE CHAMEI DE isArray, É RESPONSÁVEL POR VERIFICAR SE O OBJETO PASSADO É UM ARRAY

A SEGUNDA FUNÇÃO É A ALMA DO NEGÓCIO, A FUNÇÃO callAjax.
Segue abaixo alguns detalhes sobre os parâmetros
@CAMPO = NOME DO CONTAINER(DIV) QUE VOCÊ DESEJA ATUALIZAR
@PARAMETRO = PARAMETROS QUE DESEJA PASSAR PARA A URL (PODE SER UM ARRAY)
@CAMPOVALOR = CAMPOS QUE POSSUEM OS VALORES REFERENTES AOS PARAMETROS (A SEQUENCIA DOS VALORES AQUI DEVEM ESTAR NA MESMA ORDEM QUE VOCÊ PASSOU O PARAMETRO. TAMBÉM PODE SER UM ARRAY)
@METODO = MÉTODO GET OU POST
@VARURL = URL QUE VOCÊ DESEJA CHAMAR




Módo de utilização

Passando parâmetros e valores simples (não Array)
//TODA VEZ QUE UM COMPONENTE COM O ID "button1" FOR CLICADO, REQUISITA A FUNÇÃO JS.
$("#button1").click(function(){
callAjax('p_email', 'email', 'email', 'GET', 'verificaemail.php');
});


Passando parâmetros e valores compostos (Array)
//TODA VEZ QUE UM COMPONENTE COM O ID "button1" FOR CLICADO, REQUISITA A FUNÇÃO JS.
//PASSANDO 3 PARAMETROS PARA A PAGINA verificaemail.php
parametros = new Array(3);
parametros[0] = 'email';
parametros[1] = 'idcliente';
parametros[2] = 'idade';

//PASSANDO 3 VALORES PARA A PAGINA verificaemail.php.
//AQUI OS VALORES (id dos campos input por exemplo) DEVEM ESTAR NA MESMA SEQUENCIA DOS PARÂMETROS
valores = new Array(3);
valores[0] = 'campo_email';
valores[1] = 'campo_idcliente';
valores[2] = 'campo_idade';

O que seria enviado para a pagina verificaemail.php, seria o seguinte Querystring:
?email=valordocampo&idcliente=valordocampo&idade=valordocampo

Para chamar a função, é a mesma coisa. Idêntica como chamamos pelo primeiro exemplo:
$("#button1").click(function(){
callAjax('p_email', parametros, valores, 'GET', 'verificaemail.php');
});

A função callAjax você pode colocar dentro de um arquivo .js por exemplo, incluindo junto com sua biblioteca de scripts.

Para chamar a função como no exemplo acima, vc deve chamar dentro do ready do Jquery. Ficaria assim:

$(document).ready(function() {

$("#button1").click(function(){
callAjax('p_email', parametros, valores, 'GET', 'verificaemail.php');
});

});


Blz pessoal?
Desculpem a demora para postar.
No outro post, espero postar algumas coisas a mais sobre o Zend Framework.
Abraços...t+

terça-feira, 23 de junho de 2009

Carrinho de compras com Zend Framework

E ai pessoal,
Desculpem minha ausência, tenho me ocupado muito com alguns projetos que tenho feito por fora.

Tenho mexido bastante com o Zend Framework e só tenho uma coisa a dizer: Estou tendo bem menos dor de cabeça do que quando programava com PHP puro. Isso sem falar da organização do projeto em MVC, os benefícios do Zend_Layout, etc.

Em um dos projetos, tive que construir um carrinho de compras utilizando Session.
Eu li um livro sobre Zend Framework, que ensina a criar um carrinho de compras com o Zend_Registry.
O problema do Zend_Registry é que ele não utiliza sessões, mas sim variáveis globais.

Eu não me basiei nesse livro, então caso saiba de qual livro estou me referindo, esqueça o carrinho que você aprendeu lá caso queira fazer um carrinho baseado em Session.

Para a criação de Sessions no Zend, nós utilizamos a classe Zend_Session_Namespace();

Como essa é uma classe singleton, caso já tenha sido criada uma instância da mesma, apenas é retornado a instância já criada. Você pode tentar criá-la várias vezes, mas ela apenas retornará a instância que já foi criada, até que ela seja liberada da memória.
Ou seja, o Zend simplesmente ignora a criação do novo objeto vazio e continua a session com os mesmos valores já gravados.


Eu ajustei uma classe que peguei em um forum sobre ZF. Ela "manuseia" uma session e achei que valeria a pena incluí-la no meu projeto.

Como tive muito problemas ao postar o código nesse blog, eu printei as telas.
Pois o blog não estava permitindo que eu colocasse os conteudos

Segue abaixo a classe. Você pode ajustá-la conforme suas necessidades. Para nosso carrinho, creio que seja o suficiente da forma como a deixei.

CLASSE "CONTROLADORA" DAS NOSSAS SESSIONS


Eu já dei o name do meu namespace de carrinho, mas você pode colocar no construtor da classe um parâmetro que seria o nome do seu namespace. Caso você não de um nome para o namespace, ele adota o valor Default.
Ficaria assim: Zend_Session_Namespace('Default');


ACTION DE INCLUSÃO DE ITEM NO CARRINHO



LISTANDO OS ITENS NO CARRINHO

Para listar os itens no carrinho é simples, basta fazer um foreach da variavel carrinho, que atribuimos o valor no nosso controller: "$this->view->carrinho = $carrinho;"

$carrinho = $this->carrinho;
$chave = @array_keys($carrinho);
for($ i = 0; $i < count ($chave);$ i ++){
$indice = $chave[$i];

//CRIANDO O OBJETO DA NOSSA CLASSE DE PERSISTENCIA COM A BASE DE DADOS, DA TABELA PRODUTOS.

$produtos = new Produtos();
$where = "idproduto = ".$carrinho[$indice]['idproduto'];
//PUXANDO OS DADOS DO PRODUTO
$produto = $produtos->fetchRow($where);
}


Eu estou criando um objeto da nossa classe de persistencia (model), para poder visualizar o nome do produto, qtde em estoque, entre outras coisas.
Você pode usar seu próprio modelo.
Caso queira apenas mostrar o código do produto e quantidade escolhida pelo usuário, você poderia implementar o código abaixo:

$carrinho = $this->carrinho;
$chave = @array_keys($carrinho);

for($ i = 0;$ i< sizeof ($chave); $ i ++){
//GUARDANDO O INDICE DO ARRAY
$indice = $chave[$i];
//MOSTRANDO OS DADOS INCLUIDOS NO CARRINHO
echo $carrinho[$indice]['idproduto']." - ".$carrinho[$indice]['qtde'];

}


ATUALIZANDO E EXCLUINDO ITENS DO CARRINHO
Para atualizar ou excluir itens de um carrinho, eu coloquei um checkbox em nosso carrinho de compras, contendo o indice do mesmo ($indice), então eu aplico um submit do formulário contendo os itens incluidos.
O formulário nos enviará para uma action chamada udcarrinhoAction().

Segue abaixo minha action udcarrinho:



Caso vocês queiram apagar todos os itens do carrinho, basta usar o método emptySess da nossa classe.

Caso tenham dúvidas em como montar o formulário do carrinho, entrem em contato comigo. Farei de tudo para ajudar.

The Best regards for you guys!! ;)

quarta-feira, 29 de abril de 2009

Agrupando Erros do Zend_Form em uma mesma linha

Toda vez que utilizamos o método isValid para validar nossos campos e emitir os erros no formulário, por padrão o ZF mostra os erros em baixo de cada Elemento, que é onde fica o decorate "Errors". E talvez gostaríamos de mostrar ao usuário os erros de uma vez só, jogando tudo em apenas uma linha.

Para isso, nós utilizaremos os decorators da classe Zend_Form.

Nosso resultado final será como a figura abaixo:


Para o nosso exemplo, a seguinte classe esta montada:


class MeuForm extends Zend_Form
{

public function __construct($options = null)
{

parent::__construct($options);

$this->setMethod(’post’);

$username=new Zend_Form_Element_Text(’login’, array(

‘required’ => true,

‘label’ => ‘Login:’,

‘filters’ => array(’StringTrim’, ‘StringToLower’),

‘validators’ => array(

‘Alnum’,

array(’Regex’,false,array(’/^[a-z][a-z0-9]{2,}$/’))

)
));

$username->removeDecorator(’Errors’);



$password=new Zend_Form_Element_Password(senha’, array(

‘required’ => true,

‘label’ => ‘Senha:’,

‘filters’ => array(’StringTrim’),

‘validators’ => array(

‘NotEmpty’,

array(’StringLength’, false, array(6))

)
));

$password->removeDecorator(’Errors’);



$save=new Zend_Form_Element_Submit(’save’, array(

‘label’ => ’Salvar’,

‘required’=> false,

‘ignore’ => true,
));


$this->addElements(array($username, $password, $save));

$this->setDecorators(array(

‘FormElements’,

‘FormErrors’,

‘Form’

));

}

}




As linhas principais da nossa mudança são as seguintes:

$username->removeDecorator(’Errors’);
$password->removeDecorator(’Errors’);

Se você não utilizar o parametro removeDecorator, com certeza os erros apareceram em baixo de cada elemento de seu formulário.
Para os erros aparecerem agrupados, o seguinte decorator foi criado:
$this->setDecorators(array(

‘FormElements’,

‘FormErrors’,

‘Form’

));

quer incrementar mais ainda?
Então no lugar de criar o decorator acima, crie o seguinte decorator:

$this->setDecorators(array(

‘FormElements’,

new Zend_Form_Decorator_FormErrors(array(

‘ignoreSubForms’=>true,

‘markupElementLabelStart’=> ‘<b>’,

‘markupElementLabelEnd’=> ‘</b>’,

‘markupListStart’=>’<div>’

‘markupListEnd’ => ‘</div>’,

‘markupListItemStart’=>’<span>’,

‘markupListItemEnd’=>’</span>’,


)),

‘Form’

));


O código acima irá colocar os "Índices" dos erros em um div e em negrito e os erros dos validators (StringLength, Alnum, NotEmpty) em uma tag span.

Tenho estudado sobre como utilizar o Dojo ToolKit no ZF. Os formulários ficam show de bola!
Espero postar sobre o Dojo ToolKit no ZF ;)

Abraços Pessoal.

sexta-feira, 24 de abril de 2009

Integrando Smarty com Zend Framework

E ai pessoal...
Dando continuidade ao aprendizado do Zend Framework, escreverei como integrar o Zend framework com o Smarty Template Engine.

Com o smarty nós conseguimos separar nossas views(Front controllers) em templates. Apesar do Zend adotar o padrão MVC (Movel View Controller), nós temos algumas limitações visuais para organizar nosso código de forma que um webdesigner reconheça ou tenha uma grande noção do que está acontecendo em cada bloco de código de nossos arquivos de layout do sistema e, pelos seguidores do Smarty, não há outro template engine melhor que ele.

Um exemplo:
Toda vez que formos mostrar valores, fazer loops e decisões em nossas páginas e juntarmos tudo ao código HTML, nós temos um visual poluido de nossos arquivos deixando a manutenção mais exaustiva, sem contar que em alguns editores usados pelos webdesigners como o Dreamweaver, a tentativa de interpretação do código do dreamweaver muitas vezes desestrutura o layout do nosso site em fase de desenvolvimento.
Uma diferença de um código sem e com Smarty.
Sem Smarty: < ?php echo $nomedavariavel ? >
Com Smarty: {$nomedavariavel}

Eu li alguns artigos explicando como integrar o Smarty com o Zend...mas não gostei. Vou postar aqui da forma que eu achei menos confusa e mais fácil para manutenção:

INSTALANDO, INSTANCIANDO E CONFIGURANDO O SMARTY

Faça o download do smarty pelo link: http://www.smarty.net/download.php
Crie um diretório chamado Smarty dentro do diretório Library da sua aplicação ZF.
Copie o conteúdo da pasta Lib do arquivo de download(Smarty) para o novo diretório criado.

Dentro do diretório application do ZF, crie os seguintes diretórios: templates, templates_c e templates_cache.


include "Zend/Loader.php";
// Instancia as classes necessárias automaticamente (inclusive a do Smarty)
Zend_Loader::registerAutoload();

//Cria objeto do smarty e configura suas propriedades
$smarty = new Smarty();
$smarty->debugging = false;
$smarty->force_compile = true;
$smarty->caching = true;
$smarty->compile_check = true;
$smarty->cache_lifetime = -1;
$marty->template_dir = './application/templates/';
$smarty->compile_dir = './application/templates_c';
$smarty->cache_dir = './application/templates_cache';
//Registra o objeto criado. É por esse registro que iremos referenciar o objeto smarty em nossos controllers
Zend_Registry::set('smarty', $smarty);


Em seu controller, crie uma variável privada chamada $smarty:
class MeuController extends Zend_Controller_Action
{
private $smarty;
...
}


Chame o smarty da seguinte forma na function init() do seu controller:
public function init(){
$this->smarty = Zend_Registry::get('smarty');
}

E dentro de suas actions, passe os valores necessários para o smarty, Ex.:
public function indexAction()
{
//Cria uma variável chamada Hello com o valor Hello Word!
$this->smarty->assign('Hello', 'Hello Word!');
//Diz ao smarty qual é seu arquivo de template para ser renderizado
$this->smarty->display('arquivo_template.tpl');
}

Não esqueça de criar seu arquivo de template(dados html) dentro do diretório templates que criamos.
Caso esteja trabalhando com módulos no Zend, vc também pode fazer isso sem problemas que funciona da mesma forma.

PLUG-IN DO SMARTY PARA ECLIPSE

Como eu uso o Eclipse, existe um Suporte do Smarty para o eclipse PDT.
Vocês podem baixar nesse endereço: http://code.google.com/p/smartypdt/
Basta descompactar o arquivo no seu diretório do eclipse.
Ele é bom para verificar erros de sintaxe do Smarty e além disso, caso não tenhamos esse plugin, o eclipse fica mostrando aqueles warnings como se fossem erros de HTML.


Bom pessoal, é isso!
Hasta luego!!
;)

quarta-feira, 22 de abril de 2009

Módulos no Zend Framework

E ai pessoal,
Há um tempo atrás eu passei um sufoco ao tentar criar a separação dos meus controllers e diretórios por módulos. Nas minhas pesquisas para resolver meu problema, verifiquei que há muitas pessoas encontrando esta dificuldade e sem soluções.
Vamos imaginar que você possui um site que terá a área default(front com os usuários) e a parte de administração - admin(front dos administradores do site). É dessa forma que veremos como criar esses módulos.
Eu fiz o teste do exemplo utilizando o XamppLite 1.7.0 e o Appserv 2.5.10.
Obs.: Caso esteja tendo problemas com o .htaccess, leia mais no final do post (Dicas).

Eu cheguei a fazer testes com o Application server, mas deu um problema com relação a segurança e redirecionamentos do .htaccess. Estou entrando em contato pelo site do application server para poder solucionar o problema, mas pelo xampplite deu tudo certo.

ESTRUTURA DE DIRETÓRIOS

Deve existir várias formas de separar os módulos. Postarei a forma que obtive sucesso após bater a cabeça.
A estrutura do nosso diretório ficará como a figura abaixo:



Note que dentro de application eu criei um diretório chamado admin e outro chamado default(marquei de vermelho), que serão nossos módulos e conterão seus próprios controllers, models e scripts.

Para cada área da administração eu criei um controller, onde vc pode inserir as Actions de add, edit, etc...Assim como os arquivos phtml.
Os nomes dos arquivos phtml precisam ser iguais ao de suas Actions. Por exemplo, dentro do Controller NoticiasController, terei as seguintes actions:
public function addAction(){...}
public function editAction(){...}
e o nome de seus templates: add.phtml e edit.phtml

É dessa forma que o Zend trabalha. Caso tenha alguma outra forma que você saiba e tenha se sentido incomodado com minha observação, pode postar um comentário que ficarei feliz de saber outra forma. :)

CONTROLLERS

Como nós separamos nosso exemplo em módulos, devemos dizer ao index.php onde ficarão esses módulos.

No seu index.php, adicione a seguinte linha:
//Cria a instrancia do front_controller
$controller = Zend_Controller_Front::getInstance();

//Indica o topo do nosso diretório. por exemplo, caso o seu endereço fique: http://localhost/sistemas/Exemplo, o seu setBaseUrl deverá ficar com o valor '/sistemas/Exemplo'. No meu caso, estarei acessando http://localhost/ex_modulo
$controller->setBaseUrl('/Ex_modulo');

// mostra os erros em modo de execução
$controller->throwExceptions(true);

//Diz onde está os controllers do nosso módulo default
$controller->setControllerDirectory('./application/default/controllers');

//Aqui nós dizemos ao ZF que existe um módulo chamado admin e que seus controllers estão no diretório passado por parâmetro.
$controller->addControllerDirectory('./application/admin/controllers', 'admin');



Note que nos diretórios de controllers eu já criei os controllers para cada área de nossa administração: IndexControllers.php, NoticiasController.php e BlogsController.php .
Quando criamos nosso projeto sem módulos, o nome da classe dos módulos no nosso caso ficaria +/- assim:

public class NoticiasController extends Zend_Controller_Action(){...}
Se você tentar executar seu projeto o Zend reclamará que ele não conseguiu achar os controllers requisitados.
Como separamos nosso projeto em módulos, as nossas classes deverão conter o nome do nosso Módulo (com a primeira letra em maiúsculo) + underline"_" + NomedomoduoloController
Ficou confuso? bom, o resultado final ficaria assim:
public class Admin_IndexController extends Zend_Controller_Action(){...}
public class Admin_NoticiasController extends Zend_Controller_Action(){...}
public class Admin_BlogsController extends Zend_Controller_Action(){...}


DICAS

1 - No seu index.php indique seus include paths do seguinte modo:
setlocale(LC_ALL, 'BRA');
date_default_timezone_set('America/Sao_Paulo');
set_include_path('.' . PATH_SEPARATOR . '..' . PATH_SEPARATOR . './library'
. PATH_SEPARATOR .'./application/default/models/'
. PATH_SEPARATOR .'./application/admin/models/'
. PATH_SEPARATOR
. get_include_path());

E para facilitar nossa vida, você pode utilizar a o autoload do Zend:

include "Zend/Loader.php";
Zend_Loader::registerAutoload();

2 - Inclua o arquivo .htaccess no diretorio raiz do seu projeto que no nosso caso é o Ex_modulo:
Arquivo .htaccess:
# Rewrite Engine config
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(gif|jpg|png|css|js|controller.php|tpl|trans.php|service.php)$ index.php

# Coloca UTF-8 como charset padrao
AddDefaultCharset iso8859-1

# Desabilita a auto insercao de escapes (\)
php_flag magic_quotes_gpc off

# Desabilita as Variaveis globais
php_flag register_globals off

No appserv e wampp, é necessário descomentar a seguinte linha no httpd.conf do apache:
LoadModule rewrite_module modules/mod_rewrite.so
se não vc vai obter o erro: Internal Server error .
O Xampplite já vem com a linha descomentada por padrão (pelo menos nessa versão).

Veja que eu inseri o Charset Iso8859-1 no arquivo htacces.
Caso você não lembre que estamos setando essa configuração no .htaccess e você quer q seu projeto rode com o charset utf8 e não lembrar de mudar no seu .htaccess, você vai ter sérias dores de cabeça procurando onde esta seu problema de CharSet.

Bom pessoal, em caso de dúvidas ou caso queiram que eu envie os arquivos do Exemplo, comentem ou me enviem e-mail que enviarei os arquivos de exemplo.

Abraços e até +

quinta-feira, 9 de abril de 2009

Upload de arquivos com Zend Framework

E ai pessoal,
Depois de um longo tempo sem escrever devido à mudança de emprego que tive, escreverei hoje sobre um framework que tenho estudado, o Zend Framework.

Lembra de quando você fazia o código para upload de arquivos do seu site e tinha uma "dor de cabeça" para obter tamanho de arquivo, verificar extensão, tamanho e etc?

O Zend já faz essa brincadeira para nós. É aquela velha história de não termos que reinventar a roda ou perder tempo criando nossas proprias classes e, além de criar, fazer testes exaustivos.
Então, pq não usar um framework de confiança e já testado?

Para este tutorial, você precisa ter uma base de como funciona o Zend Framework, como carregar(include) seus arquivos com o Zend_Loader por exemplo e saber como o Zend visualiza a estrutura de arquivos do seu projeto.
Para isso, eu indico um bom tutorial para iniciantes:

http://akrabat.com/wp-content/uploads/iniciando-com-zend-framework_130.pdf

AS CLASSES

O Zend possui uma classe Zend_File_Transfer que além de nos permitir trabalhar com uploads, também nos dá uma mão para a segurança em download de arquivos do nosso site.

Para conseguirmos indicar para onde irá nossos arquivos e checar algumas configurações, utilizaremos a classe Zend_File_Transfer _Adapter_Http

EXEMPLOS


Vamos criar um formulário que conterá um input file 'uploadedfile', que será responsável por carregar nosso arquivo (lembrando que precisamos ter o enctype preenchido sempre que formos mexer com arquivos em nossos formulários).


Arquivo:




Além de fazer o formulário de envio via HTML, podemos usar também a classe
Zend_Form_Element_File (O que eu acho melhor, veja o pq).
Exemplo:


$element = new Zend_Form_Element_File('uploadedfile');
$element->setLabel('Enviar arquivo:')
->setDestination('c:\Temp');

// Quero que o usuário envia apenas 1 arquivo
$element->addValidator('Count', false, 1);
// com o tamanho limite de 100K
$element->addValidator('Size', false, 102400);
// apenasJPEG, PNG, e GIFs
$element->addValidator('Extension', false, 'jpg,png,gif');
$form->addElement($element, 'foo');


//Setando o destino de nossos arquivos de upload (Caso use o exemplo de formulário em html)
$adapter = new Zend_File_Transfer_Adapter_Http();

$adapter->setDestination('C:\temp');

if (!$adapter->receive()) {
$messages = $adapter->getMessages();
echo implode("\n", $messages);
}


//Carregando os arquivos para o servidor
$upload = new Zend_File_Transfer();

// Retorna as informações referente ao arquivo
$files = $upload->getFileInfo();

foreach ($files as $file => $info) {
//O usuário escolheu um arquivo ou o campo esta vazio?
if (!$upload->isUploaded($file)) {
print "Pq vc nao escolheu o seu arquivo e deixou o campo vazio?";
continue;
}

// Tudo ok?
if (!$upload->isValid($file)) {
print "Desculpe, mas o arquivo $file não é o que queremos.";
continue;
}
}

//Envia para o servidor
$upload->receive();

// Obtem o nome do arquivo
$names = $upload->getFileName('
uploadedfile');

// Retorna o tamanho do arquivo
$size = $upload->getFileSize(
'uploadedfile');

// Retorna o mimetype do arquivo (Se é jpeg, gif, pdf, etc)
$type = $upload->getMimeType('
uploadedfile');


Que ajuda o Zend nos fornece né?
Bom, é isso ai!
Para dúvidas, consultem o manual da Zend:

http://framework.zend.com/manual/en/zend.file.html

quarta-feira, 4 de março de 2009

Trabalhando com arquivos XML no PHP

E aew pessoal.
Esses dias eu criei uma aplicação simples em PHP para ser utilizada em Pocket PC, ou seja, páginas WAP só que envolvendo o PHP como linguagem para acessar os dados de uma base MySQL.
Mas como eu iria dizer ao aplicativo PHP que eu teria que acessar a base do servidor x, y ou z?
Foi ai que eu criei um arquivo XML não só contendo informação da base de dados, mas também outros dados que seriam interessantes quando não houvesse conexão com a rede wireless.

ARQUIVOS XML

O XML trabalha muito parecido com o html em relação a criação, abertura e fechamento de Tags. A diferença é que todo XML é case sensitive. Outra característica parecida com o HTML, é que você pode definir o character code, segundo o padrão W3C.

Um exemplo de um arquivo XML:



Este é um exemplo simples de um arquivo XML, contendo como nódulo pai e seus filhos chamados nome.


CARREGANDO ARQUIVOS XML

Para interpretar um documento XML, utilizamos a função simplexml_load_file(). Esta função realiza a leitura de um documento XML, criando um objeto do tipo SimpleXmlElement. Caso o documento esteja mal formatado, com algum erro de case sensitive ou até mesmo não seja um documento XML, essa função retornará FALSE.

Vamos criar um documento PHP que lerá o arquivo XML do exemplo acima. Vamos chamar o arquivo XML de estados.XML.

< ?
//interpreta o documento XML
$xml = simplexml_load_file('estados.XML');

var_dum($xml);

?>

Obs.: A função var_dump() analisa o objeto resultante.

O resultado será o seguinte:

Object(SimpleXMLElement)#1 (4) {
["nome"]=> string(9) "SAO PAULO"
["nome"]=> string(14) "RIO DE JANEIRO"
["nome"]=> string(17) "RIO GRANDE DO SUL"
["nome"]=> string(4) "ACRE"
}


Você pode pegar os dados de um arquivo xml pelos índices de seus nodes. Exemplo:

< ? //interpreta o documento XML
$xml = simplexml_load_file('estados.XML');

echo "Estado: ' . $xml->estados->nome[0] . "\n";
echo "Estado: ' . $xml->estados->nome[1]. "\n";
echo "Estado: ' . $xml->estados->nome[2]. "\n";
echo "Estado: ' . $xml->estados->nome[3];
?>


Você também pode mudar o valor de um node, como no exemplo a seguir:

< ? //interpreta o documento XML
$xml = simplexml_load_file('estados.XML');

//Modificando o valor do primeiro estado e mostrando a seguir
$xml->estados-nome[0] = "MATO GROSSO DO SUL";
echo "Estado: ' . $xml->estados-nome[0];

?>


Você pode utilizar a função foreach para mostrar todos os subelementos nome do documento:

< ? //interpreta o documento XML
$xml = simplexml_load_file('estados.XML');

foreach($xml->estados->nome as $estado){
echo $estado . "\n";
}
?>


FUNÇÕES NATIVAS DO PHP5 PARA MANUSEIO DE ARQUIVOS XML

Existem algumas funções que auxiliam no uso do XML, como incluir novo node, Listar atributos, visualizacão de nodes filhos, gravar dados em um novo arquivo XML, e muitos outros.

Para visualizar e aprender essas funções, nada melhor que o bom e velho PHP.net (www.php.net) que na minha opinião, é o melhor manual/tutorial para linguagem de programação feito até hoje.
Segue abaixo algumas funções que sempre costumo usar:

asXML() - Retorna uma string XML formatada representando o objeto, bem como seus subelementos.
addChild() - Adiciona um novo elemento ao node especificado.
file_put_contents - Sobrepõe um arquivo XML com novos dados.

Qualquer dúvida, é só potar um comentário...
Abraços.

quarta-feira, 21 de janeiro de 2009

Votação de produtos com porcentagem e barra de progresso

E ai pessoal, tudo tranquilo?
Depois de mais ou menos 1 mes de ferias do blog, voltei aqui para postar mais uma implementação q fiz em um dos meus trabalhos.

No momento eu estou fazendo um site em PHP, onde há produtos e cada produto possui uma enquete com 5 opções:
1 - Péssimo produto
2 - Razoável
3 - Bom
4 - Muito bom
5 - Excelente

Eu não explicarei exatamente como fazer a enquete, ou seja, como incluir uma nova enquete ou como fazer com que a página receba os votos do usuário. Irei apenas enfatizar como pegar o total de votação e mostrar a porcentagem de cada opção e além disso, como mostrar o total da votação em uma barra de progresso horizontal.


TABELAS UTILIZADAS

Segue abaixo como estao as minhas tabelas na base de dados:

USUARIOS
-------------------
idusuario INT AUTOINCREMENT NOT NULL
nome VARCHAR(30) NOT NULL

PRODUTOS
-------------------
idproduto INT AUTOINCREMENT NOT NULL
nome VARCHAR(30) NOT NULL

VOTACOES_PRODUTOS
--------------------
idusuario INT
idproduto INT
data_votacao DATETIME
declaracao TINYINT (Campo que determina a opção do voto)

Bom, agora com nossas tabelas, irei mostrar a logica de como fazer a porcentagem de votos para cada opção.


PORCENTAGEM DE VOTOS POR OPÇÃO VOTADA


Para calcular a porcentagem de votos que uma opção teve, devemos fazer o seguinte calculo:
porcentagem é = quantidade total . (quantidade de votos/100)

Quantidade total = Número de registros da tabela votacoes_produtos.
Ex.: (SELECT COUNT(*) as qtde_total FROM votacoes_produtos)

Quantidade de votos = Número de votos que o produto obteve na determinada opção.
Ex.: (SELECT COUNT(*) as qtde_votos FROM votacoes_produtos WHERE idproduto = 3 and declaracao = 4)

ficaria assim em PHP:
$porcentagem = $qtde_total*($qtde_votos/100);
echo $porcentagem;

RECEBENDO A PORCENTAGEM DE TODAS AS OPÇÕES

Imagine a primeira opção (Péssimo produto) como 0% e a quinta opção (Excelente) como 100% da nossa barra de progresso.
Precisamos criar uma forma de preencher nossa barra de progresso pelas votações recebidas, tendo votos da primeira e última opção ou não.

Para fazer isso, faremos uma regra de três.
Vamos supor que 5 pessoas votaram, seus votos foram: 5, 3, 5, 1 e 2
A soma de todas as votações(opções), seria 16...correto?
O máximo de número de votos seria 5x5 = 25(100%)
Ai você faz aquela pergunta para obter a porcentagem: se para 25 pontos eu tenho 100%, quantos % eu obtive com 16 pontos?
Fácil!
25 = 100%
16 = x

x = (100*16)/25
x = 64%

Como diz o professor de inglês Arthur que aparece no youtube: IT'S EASY!!!


CRIANDO A BARRA DE PROGRESSO

Nossa barra de progresso será feita no esquema de Estrelas.
Faça download das seguintes imagens:




Para criar a barra de progresso, utilizaremos HTML puro.
Crie uma tabela com 100 pixels de largura, 0 de borda, cellpadding e cellspacing.
Dentro dessa nova tabela criada, insira outra tabela com 100% de largura, 0 de borda, cellpadding e cellspacing.

Na coluna(TD) da primeira tabela criada, insira o seguinte código CSS: style="background-image:url(estrela02.gif); background-repeat:no-repeat;"
Na coluna(TD) da segunda tabela criada, insira o seguinte código CSS:
style="background-image:url(estrela01.gif); background-repeat:no-repeat"

No width da segunda tabela criada, coloque o seguinte valor: width="< ? echo $x; ? >"
onde $x é o novo valor q obtemos com a regra de 3 que criamos acima.
Note que conforme a porcentagem, as estrelas coloridas sobrepõe as estrelas apagadas.

É isso galera..
Em caso de dúvidas, envie comentário q tentarei responder o mais rápido possível.
Até lá.

terça-feira, 16 de dezembro de 2008

Grid com AJAX, Paginação, Ordenação e Filtro no PHP

Estou em meio ao desenvolvimento de um site em PHP e precisei de uma Grid que além de me auxiliar na paginação, busca e ordenação dos registros, também fosse em AJAX.
Depois de procurar no site PHP Classes (http://www.phpclasses.org/) achei uma Grid bem interessante chamada EyeDBGrid.

Para download da classe, acesse o link: http://www.phpclasses.org/browse/package/4951/download/zip.html

Com ela nós conseguimos recuperar dados de qualquer base Mysql.
Segue abaixo uma imagem de exemplo:


















Após feito o download você terá as classes, imagens e folhas de estilo usadas pela Grid.
Rode o exemplo no seu servidor.
A classe utiliza as proprias funções "mysql_", sendo assim, não é preciso de ativação das classes PDO pelo servidor.

Eu não tenho muito o que falar sobre as configurações e adaptações da Grid para seu sistema, pois todos os exemplos e arquivos contendo as classes estão comentados.

Espero ter ajudado vocês.
Abraços.

sexta-feira, 5 de dezembro de 2008

Arrays (Vetores/Matrizes) no PHP

Quando comecei a programar, tive muitas dúvidas de como usar arrays ou até mesmo o que é um array, vetor ou matriz.

Esses dias no meu trabalho meu amigo meio "Bixinha" me perguntou:
Aiiii...como que eu posso armazenar valores diferentes em uma mesma variável?
Dai foi então que eu expliquei: ARRAY!

O QUE É UM ARRAY?

Essa foi a pergunta da minha linda namorada antes da prova da faculdade.
O que eu expliquei pra ela foi o seguinte:
Array, é como se fosse um livro.
Dentro de um livro, possuimos índices e, em cada índice, o livro possui um valor, que é o conteudo daquele indice.
Exemplo:
livro[0]
livro[1]
livro[2]

No exemplo acima e seguindo o exemplo que dei à minha namorada sobre o livro, lemos o seguinte:
Livro índice 0
Livro índice 1
Livro índice 2
Então, esse livro possui 3 índices e cada índice do livro, possui textos diferentes.
O array trabalha da mesma forma.
Na programação, nós podemos dar valores aos índices de uma variável do tipo array.

Exemplo:
livro[0] = 'Branca de neve encontrou os sete anões'
livro[1] = 'Branca de neve foi morar com os 7 anões'
livro[2] = 'Branca de neve mordeu a maça da bruxa e dormiu eternamente'


UTILIZANDO ARRAY NO PHP


Uma dica que eu dou para as pessoas que tiram dúvidas comigo, é: Consulte o manual!!
O manual do php é ótimo e além de fornecer informações sobre as funções e estruturas da linguagem, contém exemplos enviados pela comunidade "PHPense".
Algumas funções já possuem manual em português.
Para acessar o manual, basta entrar em www.php.net

Meu patrão sempre me fala que manual é o guia dos "burros", mas na minha opinião, os espertos não perdem tempo fazendo besteiras e já os consultam logo de cara!

Existem várias formas de criar um array, a forma mais fácil na minha opinião é descrita abaixo:

$livro[0] = "Branca de neve encontrou os sete anões";
$livro[1] = "Branca de neve foi morar com os 7 anões";
$livro[2] = "Branca de neve mordeu a maça da bruxa e dormiu eternamente";

Além de criar vetores por índices como feito acima, podemos criar vetores com seus índices e referenciá-los por um nome, exemplo:

$livro[0]["titulo"] = "Branca de neve e os sete anões";
$livro[0]["autor"] = "Mariana";
$livro[0]["anopublicacao"] = "2000"

$livro[1]["titulo"] = "Cinderela";
$livro[1]["autor"] = "Maurício";
$livro[1]["anopublicacao"] = "1980"

O que o array acima esta fazendo, é criar uma "tabela" com seus índices e valores para cada "título"

Imagine agora os dados digitados acima em uma tabela do word, que nas colunas contenha os títulos e valores:

Título | Autor | Ano Publicacao
Branca de... Mariana 2000
Cinderela Maurício 1980

É exatamente isso que estou fazendo ao criar o array.

ONDE E QUANDO USAR ARRAY?


O array é muito utilizado quando você deseja guardar em memória, valores diferentes em uma mesma variável.
Essa função é muito utilizada em E-commerce, para inserir produtos em um carrinho de compras. Enquanto o usuário que navega o site nao finalizar a compra, todos os itens que ele solicitou ficam guardados em um array, até que na finalização da compra, o sistema passa todas as informações armazenadas do array para a base de dados.

No exemplo do carrinho de compras, como queremos guardar os valores enquanto o usuário visita o site e mantê-los mesmo que ele acesse diferentes páginas do mesmo site, podemos criar variáveis de Sessão ($_SESSION) como arrays. Tá ai a dica.



FUNCÕES NATIVAS DO PHP PARA O USO DE ARRAY

Existem algumas funções no PHP que nos auxilia no uso de array. Eu citarei as que eu acho mais importantes:

count() — Conta o número de índices de um array
array_key_exists — Checa se uma chave ou índice existe em um array
array_keys — Retorna todas as chaves de um array
array_values — Retorna todos os valores de um array
print_r — Retorna valores de uma variável
array_search — Procura por um valor em um array e retorna sua chave correspondente caso seja encontrado