KISS - Keep it simple, stupid!

Logando queries no Shell do CakePHP

postado por Gabriel Gilini em 06/06/2011 14:59:53

Se você é como eu, adora criar shells em projetos CakePHP. São fáceis, herdam pouca estrutura e te dão acesso a quase tudo que precisa para tarefas de manutenção.

Apesar de todos os pontos positivos, passei por um problema sério recentemente: a incapacidade de se extender sua classe super. Todo shell deve herdar a classe Shell, que é declarada no core do CakePHP (cake/console/libs/shell.php). Este pequeno fato torna inviável qualquer mudança na classe Shell, já que alterar código terceiro em um projeto não é algo que eu considero inteligente.

A solução foi criar uma classe intermediária, assim como temos o AppController e o AppModel, podemos ter o AppShell.

Crie um arquivo app.php no caminho app/vendors/shells/app.php e crie sua classe AppShell:

<?php
class AppShell extends Shell
{
}

Ok, temos uma classe intermediária que podemos extender à vontade, é só fazer com que nossos shells extendam AppShell, com um pequeno porém: o Cake não vai incluir por padrão o arquivo de sua base class. E agora?

Simples! Vamos incluir o arquivo usando o método canivete suíço App::import.

<?php
App::import('Shell', 'App');
class SomeApplicationSpecificShell extends AppShell
{
    // Call some parent methods
}

E é só isso!

Mas o que você vai colocar na sua super classe? Eu tenho uma sugestão.

Sinto muita falta do element sql_dump, que apresenta um log de todas as transações ocorridas nos datasources durante o load da página. Abri o código do element e portei para nossa classe de shell:

<?php
class AppShell extends Shell
{
    public function getDatabaseLogs()
    {
        if (!class_exists('ConnectionManager') || Configure::read('debug') < 2) {
            return false;
        }
 
        $sources = ConnectionManager::sourceList();
        if (!isset($logs))
        {
            $logs = array();
            foreach ($sources as $source)
            {
                $db =& ConnectionManager::getDataSource($source);
                if (!$db->isInterfaceSupported('getLog'))
                {
                    continue;
                }
                $logs[$source] = $db->getLog();
            }
        }
 
        $out = array();
        $out[] = "Nr\tQuery\tError\tAffected\tNum. rows\tTook (ms)";
        foreach ($logs as $source => $logInfo)
        {
            $text = $logInfo['count'] > 1 ? 'queries' : 'query';
 
            $tmp = array();
            foreach ($logInfo['log'] as $k => $i)
            {
                $tmp[] = ($k + 1) . "\t" . h($i['query']) . "\t{$i['error']}\t{$i['affected']}\t{$i['numRows']}\t{$i['took']}";
            }
 
            $out[] = array(
                sprintf('(%s) %s %s took %s ms', $source, $logInfo['count'], $text, $logInfo['time']),
                $tmp
            );
        }
 
        return $out;
    }
}

Como vocês podem ver, simplesmente peguei o conteúdo do element sql_dump, removi a marcação, inseri tabulações para facilitar a visualização, joguei tudo num array e simplesmente retornei. Fica a cargo do desenvolvedor do projeto tratar e exibir a saída.

E você, que método é imprescindível em seus scripts shell?

Tags: , ,
Topo

Sem comentários

Lib para lidar com arquivos Zip no CakePHP

postado por Gabriel Gilini em 26/04/2010 17:11:42

Em um projeto recente, precisei extrair arquivos zip no server, e no
processo criei uma classe para abstrair a manipulação dos arquivos.

Como no Dreamhost o PHP não vem com a zlib habilitada, não tem como
usar a ZipArchive, o que facilitaria muito as coisas. Mas o bom é que
o zlib é instalado no server, e os comandos do PHP de execução de
programas são habilitados, então criei a classe utilizando o `exec’
para chamar o `unzip’ e extrair os arquivos.

A classe está bem simples porque só implementei o necessário para meu
projeto, mas é um esqueleto para quem precisar de algo mais completo.

Evitei o uso de expressões regulares por questão de performance. Aí vai o código:

Coloquem no diretório APP/lib, e usem assim:

Tags: , , ,
Topo

2 Comentários

Galeria de imagens similar à da Apple Store

postado por Gabriel Gilini em 31/03/2010 11:42:05

Semana passada o dgmike fez um desafio em seu blog. O objetivo era construir uma galeria de imagens igual à vista na Apple Store do zero, e obviamente sem consultar o fonte do original.

Decidi que era uma boa oportunidade para treinar alguns conceitos de scripting e também divulgar meu trabalho. Além disso, vinha procurando uma desculpa pra trabalhar com a My Library; melhor lib JavaScript já concebida, se você me perguntar.

Meti a mão na massa no fim de semana, e depois de quebrar a cabeça pra deixar algumas coisinhas redondas, consegui terminar uma primeira versão do script. Não testei extensivamente, mas sei que funciona em IE7, IE8, Opera8-10, Chrome e Firefox 2+.

Dê uma conferida no meu trabalho, e diga o que achou aí nos comentários. Se encontrar qualquer bug ou tiver alguma sugestão, vou ficar feliz em ouvi-lo.

Update:
David Mark was nice enough to link my gallery at MyLib’s website!
Thanks, David!

Tags: , , ,
Topo

5 Comentários

JavaScript: buscar a posição de um elemento em uma matriz

postado por Gabriel Gilini em 30/12/2009 16:00:03
Não há tags para este post

Recebi uma pergunta curiosa no Aardvark há pouco, perguntando se eu não conhecia algum código JavaScript que buscasse a posição exata de um elemento dentro de um array multidimensional — matriz — qualquer.

Não é novidade pra ninguém que eu me divirto escrevendo código nessa linguagem, então resolvi bolar alguma coisa pra resolver o problema do rapaz em necessidade. Aí vai o código (gist):

Exemplo de uso:

No tags for this post.
Topo

1 Comentário

Criando thumbnails no shell do Linux de maneira simples

postado por Gabriel Gilini em 25/11/2009 19:59:08
Não há tags para este post

Hello, peeps.

Hoje precisei converter um bocado de imagens para um tamanho reduzido, e como um bom linuxer, fui procurar como fazer isso no shell.

Uma pesquisadinha rápida no Google, e trombei com esse “how to”. Simples e direto, resolveu minha dúvida. Chequei se o ImageMagick já estava instalado, e estava. Mas esse script que o cara colocou no tutorial tá meio pobre, não dá pra passar nada por parâmetro. Cada vez que eu precisar disso vou ter que abrir o script e modificar? Ah, não.

Dez minutinhos de vim aberto depois, surge o thumbalizr:

exemplo de uso do thumbalizr

Você tem que passar width OU height (eu sei, tá errada a marcação dos parâmetros no exemplo de uso, se alguém souber o certo me fala), e pode passar uma string pra ser inserida antes do nome original da imagem. Caso contrário, as imagens serão substituídas.

UPDATE:
Agora o script aceita a flag “-a string_pra_concatenar” que concatena uma string no final do nome do thumbnail. E também fiz algumas mudanças pra compatibilidade.

Para “thumbalizar” imagens em vários diretórios, faça algo como:

Aí vai o código do script:

Ou você pode baixar o script aqui.

No tags for this post.
Topo

Sem comentários

O IE6 é apenas mais um navegador

postado por Gabriel Gilini em 19/07/2009 16:06:54
Não há tags para este post

Em todo blog de desenvolvimento o assunto vem sendo o mesmo nos últimos dias: a morte do IE6. O Digg anunciou que não suporta mais o navegador, depois veio o Youtube, e tenho certeza que muitos outros estão seguindo a mesma estratégia dos gigantes.

Por todos os cantos da Internet se escutam exaltações de alegria: “hacks para PNG não mais”, “seletores CSS3!”, “HTML5″, e etc. E a cada vez que leio algo nesse sentido, sinto uma pontada de pesar por saber que essas pessoas não entendem o que é desenvolver pra web, elas acreditam que dando suporte às funcionalidades conhecidas de um punhado de navegadores que aparecem nas estatísticas é o necessário para dar suporte cross-browser. Então me pergunto: o que adianta bradar aos quatro ventos que desenvolve nos padrões de acessibilidade, sendo que na hora de escrever um script não leva em conta que os navegadores utilizados por deficientes visuais, por exemplo, são praticamente desconhecidos para os desenvolvedores. Eu não sei qual punhado de funcionalidades um navegador desses suporta, mas é meu papel garantir que pelo menos uma experiência minimalista de uso seja viável em qualquer navegador.

Não me vejo no direito de excluir algumas pessoas de utilizarem minha interface porque elas não usam um navegador que eu conheça ou goste, mas parece-me que muita gente não se importa com esses “excluídos”. Ontem, depois de ler o milésimo post falando como o IE6 é(era) a praga da web, resolvi dissertar brevemente sobre o assunto, e como gostei do que escrevi, vou reproduzir o texto do comentário aqui ipsis litteris.

Eu já cansei de falar isso, mas vamos lá.

Todo esse chororô dos desenvolvedores no que concerne ao IE6 é, no mínimo, “overrated”. Eu me sinto na obrigação de escrever código que funcione (mesmo que de maneira básica) em qualquer navegador. E sabem o que é mais interessante? Pra 99,9% dos projetos, não é nem um pouco difícil dar suporte ao IE6, o problema é que as pessoas desistiram de aprender JavaScript para usar cegamente essa aberração chamada jQuery, que até pouco tempo atrás abusou de user-agent sniffing, e que atualmente trocou pelos piores exemplos de feature testing que já vi na vida, se é que posso chamar aquilo de feature testing, tá mais pra object inference. Aí quando o cara testa no IE6 e vê as coisas dando errado, começa a meter a boca no navegador, mas mal sabe ele que o script que ele confia tão cegamente está fazendo tudo errado.
O meu ponto é que não é tão dificil escrever código cross-browser quando os John Resigs da internet pintam a todo momento.

Quanto ao CSS, sim o IE6 tem um suporte bem fraco a CSS2.1, mas existem os comentários condicionais. É simples fazer uma versão ‘lo-fi’ do design para IE6 utilizando um stylesheet alternativo. E pra quem ainda não sabe, esses fixes de PNG introduzem vários crashes totalmente imprevisíveis. O que você prefere, utilizar PNG 8bit ou CRASHAR o navegador de seus usuários?

Por fim, gostaria de dizer que sim, o IE6 está deixando de ser utilizado pela maioria, mas sempre existem pessoas que não podem atualizar, ou pessoas que utilizam um browser que nem entra nas estatísticas, algum dos muitos ‘flavors’ do IE6 que saíram ao longo dos anos. Acho que dá pra entender como é pointless ficar malhando um navegador, certo? Boas práticas de desenvolvimento contornam todos esses problemas.
O que falta na web são pessoas que realmente saibam o que estão fazendo e não navegadores com melhores capacidades.

E você, o que acha?

No tags for this post.
Topo

29 Comentários

Referências Circulares e Memory Leaks

postado por Gabriel Gilini em 15/07/2009 15:04:42
Não há tags para este post

Bom, o Lucas já me cobrou e eu nem tinha percebido que não postei a apresentação aqui hehe, mas aí vai! Uma breve apresentação sobre referências circulares no DOM e como elas podem vazar muita memória no IE 6 e anteriores.

No começo também falo sobre resolução de identificadores e como funciona o contexto de execução quando uma função é criada. Isso é necessário pro entendimento a fundo do que causa esses memory leaks, mas o mais importante para todos os desenvolvedores está nos últimos slides, onde mostro o que é uma closure, como as referências circulares más são formadas e como fazer para evitá-las.

Qualquer dúvida que tiverem, digam nos comentários e ficarei feliz em responder.

Aproveito também para convidar novamente todos que forem de Londrina a participar dessas apresentações, vamos tentar realizá-las a cada uma ou duas semanas.

No tags for this post.
Topo

3 Comentários

Creative Commons License
Sou Ágil: KISS em http://kiss.souagil.com.br está licenciado sobre
Creative Commons Attribution-Share Alike 2.5 Brazil License.

souÁgil