Como o Wordpress me desapontou

Fui acessar meu blog e descobri, espantado, que minha conta de hospedagem estava suspensa. E eu já estava até pensando que todo mundo fala mal de hospedagem, mas a Hostdime ainda não tinha me decepcionado (apesar deles terem me empurrado o tal plano de hospedagem). Nunca tive do que reclamar.

Entrei no serviço de helpdesk e descobri que já havia um ticket aberto. Achei muito estranho e fui ver o que era. A administração da Hostdime me disse que alguma tarefa cron estava prejudicando o desempenho do servidor. Nunca criei nenhuma tarefa cron. Eles anexaram um screenshot que indicava o problema no arquivo 'wp-cron.php'. Este arquivo faz parte do Wordpress. Então, a culpa não é da Hostdime afinal.

Como havia adicionado alguns plugins recentemente, acreditei que algum deles estava causando problemas (especialmente um que faz backup automático). Fuçando no cPanel achei a lista de serviços rodando e também o consumo de CPU/RAM. O indicador de CPU estava no vermelho (embora ainda não entenda muito bem aqueles números). Desativei o plugin, mas não fez nenhuma diferença.

Então desativei e exclui todos os plugins recém-adicionados, já que antes eu nunca tive problemas desse tipo. A carga de CPU abaixou e ficou no verde. Fiz isso hoje de manhã, antes de ir pro trabalho, já que não consegui dormir direito esta noite e acordei antes do despertador. A esta hora eles já tinham reativado minha conta.

Quando estava voltando do trabalho, hoje à tarde, vi no celular um e-mail novo. A equipe da Hostdime informou que a utilização de CPU continuava alta. Exclui todos os plugins, deixei o WP rodando seco. Não me preocupei muito em apagar, pois ontem mesmo fiz backup de tudo (exportei o banco de dados do MySQL e baixei todos os arquivos pelo FTP). Ainda assim ele consumia muito da CPU. Daí eu lembrei que atualizei a versão do WP ontem. Só pode ser isso.

Hora de googlear. Percebi que muita gente teve o mesmo problema que eu: a empresa de hospedagem reclamando do alto consumo de recursos. Muitos blogueiros, como eu, preferem servidores compartilhados, pois são mais baratos e são suficientes para o baixo tráfego. Mas este tipo de problema pode ocasionar a suspensão do site para não prejudicar os outros que estão hospedados.

E teve gente que teve este problema justamente quando atualizou o WP para a última versão (2.9.2). Procurei alguma solução, mas não tive muito sucesso. Aparentemente, plugins de cache, como o famoso WP-Cache, amenizam a utilização de CPU pelo WP. Mas não é uma solução muito eficiente, pois enquanto ainda não tiver feito o cache, o problema continua. Não queria ter minha conta suspensa de vez.
Tomei uma atitude drástica: apaguei os arquivos principais do WP, aqueles que ficam na raiz do site. Mas o consume de recursos só abaixou quando exclui o banco de dados e a conta associada. Por fim, apaguei todos os arquivos do servidor. A culpa era do Wordpress afinal.

O problema do Wordpress é o seguinte: não existe nenhum meio prático dele agendar tarefas para execução (os famosos 'cron jobs'). Então, a cada vez que uma página é aberta, ele executa a função 'wp_cron()' que verifica se há tarefas pendentes (e as executa se houver). Além disso, cada plugin e algumas inclusões em sua página gera uma requisição nova para o banco de dados. Assim, para cada visitante em cada página ele faz dezenas de requisições MySQL e, de quebra, ainda executa uma ou outra tarefa pendente. Mesmo um baixo tráfego pode gerar um alto consumo de recursos. E não é de hoje que o WP é assim.

O WP-Cache (ou o WP-Super Cache) cria cópias estáticas das páginas do blog (um html puro, sem funções de servidor). Isso evita as dezenas de requisições ao banco de dados. Isso também impede a execução das tarefas cron, o que pode ser um problema. Mas o cache não funciona com usuários logados. No caso de um blog, como o meu, só existe um usuário registrado: eu mesmo. Então, basta eu acessar o blog de vez em quando para que as tarefas sejam executadas. Como disse o Jeff Atwood, há mais de um ano, é "absolutamente irresponsável que a funcionalidade do WP-Cache não esteja já incluída no Wordpress".

Por enquanto, redirecionei o endereço para o Blogger, mas ainda não atualizei os posts, vou fazer isso com o tempo, já que não há nenhum método fácil de importar (ouvi dizer que há alguns scripts em python, mas são poucos posts, posso fazer isso na mão mesmo). Não pretendo continuar com o Blogger por que vejo muitos problemas de usabilidade, bem diferente do Wordpress. Falam também dos zilhões de plugins, mas como eles só pioram a situação, não faz tanta diferença.

Vou instalar o PHP + MySQL aqui e testar o consumo de CPU do blog, através do backup que fiz. Se o cache resolver, volto pro Wordpress. Também testarei, juntamente, a solução de tornar os 'cron jobs' agendados de verdade, ao invés de executar na chamada da página. Mas acho que vou procurar outro CMS. E agora já sei quais os defeitos que devo evitar.

E assim o Wordpress me desapontou.
Clique e diga o que achou do café

Novo Endereço

O blog Código com Café agora está disponível em www.codigocomcafe.com. Clique e diga o que achou do café

Validando datas com JavaScript e Expressões Regulares

Expressões Regulares, conhecidas também como regex, são muito úteis na área de programação. Uma das utilidades das ERs é a validação de dados.

Estava estudando ERs e, para treinar, decidi fazer um sistema de validação de datas em JavaScript, algo bastante útil, embora já existam funções prontas que fazem isso, como no jQuery, talvez no futuro eu cite algumas dessas funções.

Validar datas com ERs é útil porque elas são aceitas em várias linguagens diferentes, assim o seu script em PHP (ou outra linguagem de servidor) pode validar novamente os dados, por segurança, usando a mesma ER. Você não precisará se dar ao trabalho de escrever um novo código.

Existem duas maneiras de se definir uma ER em JavaScript:
var regex = /regex/;
//ou
var regex = new RegExp ("regex");
Sempre tomando cuidado para escapar os caracteres corretamente.

Validando Datas

Vamos ao que interessa. Em primeiro lugar vamos definir uma ER genérica, depois vamos melhorando-a até chegar naquilo que queremos (preste atenção no escape do caractere '/').
var regex = /..\/..\/..../;
Isso reconhece qualquer coisa, como "e3/34/e %[", e isso não é o que queremos. Vamos limitar apenas a números (\d). Além disso, a data deve ser a única coisa no campo, então vamos dizer que é no começo da linha (^) e que também é no final da linha ($).
var regex = /^\d\d\/\d\d\/\d\d\d\d$/;
Ok. Mas isso aceitaria algo como "43/56/9999", temos que limitar o dia até 31 e o mês até 12. E nenhum dos dois pode ser "00". Então o dia deve ser 0 e um número entre 1 e 9, 1 ou 2 e um número ou 3 e 0 ou 1. Algo parecido para o mês. O ano deve ser entre 1900 e 2099. Vamos agrupar cada pedaço, para ficar mais fácil (ou não).
var regex = /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/((19|20)\d\d)$/;
Bom, o dia pode possuir apenas um dígito se estiver entre 1 e 9. O mesmo vale para o mês. O ano também pode ser no formato reduzido de apenas dois dígitos. Vamos deixar algumas coisas opcionais (?).
var regex = /^(0?[1-9]|[12][0-9]|3[01])\/(0?[1-9]|1[0-2])\/((19|20)?\d\d)$/;
Está ficando bonito, não é? Agora vem o problema. Uma data do tipo "31/4/09" é válida, mas abril não tem dia 31. Teremos que dividir por mês, permitindo a quantidade de dias apropriada. Existem basicamente dois jeitos de se fazer isso. O primeiro é mantendo o intervalo de dias inteiro para cada tipo de mês (29, 30 ou 31 dias). Outro modo seria permitir 28 dias para todos os meses, 29 e 30 para todos menos fevereiro e 31 para os meses de 31 dias. Vou usar essa segunda maneira, porque deixa a ER menor e mais fácil de entender (às vezes uma maior é mais fácil de entender, nesse caso deixe ela maior). O agrupamento é importante, pois o operador OU (|) é o último da lista de precedência.
var regex = /^(((0?[1-9]|1\d|2[0-8])\/(0?[1-9]|1[0-2]))|
 //28 para todos os meses
((29|30)\/(0?[13456789]|1[0-2]))|
 //29 e 30 para todos menos fevereiro
(31\/(0?[13578]|1[02])))
 //31 para jan, mar, mai, jul, ago, out e dez
\/((19|20)?\d\d)$/;
Lembre-se que ERs em JavaScript não aceitam comentários e muito menos quebras de linha,eu só fiz isso para explicar as partes da ER. Se achar que precisará comentar, use o outro formato de definição, quebrando a string passada ao RegExp (nesse caso, lembre-se que a barra inversa '\' precisa ser escapada '\\'). Nossa ER está quase pronta. O único defeito é que ela não aceita o dia 29 de fevereiro, o que é válido nos anos bissextos. Não podemos deixá-la aceitar o dia 29/2 em todos os anos, então vamos deixar ela do jeito que está e apenas acrescentar uma condição.

Mas essa condição não é exatamente simples. Um ano é bissexto se for divisível por 4. Se termina com 00, o ano é bissexto se for divisível por 400. 2000 é ano bissexto, mas 1900 não é. Um número é divisível por quatro se o número formado pelos dois últimos dígitos for divisível por quatro. Isso só é possível de se fazer com ER porque a tabuada do 4 segue um padrão peculiar. Dos dois dígitos, se o primeiro for par (0 é par) então o segundo deve ser 0, 4 ou 8 e se o primeiro algarismo for ímpar o segundo deve ser 2 ou 6. Com ER, isso ficaria assim:
var regex = /\b\d*(([02468])[048])|([13579][26])\b/;
Essa é uma ER que casa com qualquer número múltiplo de 4 (de pelo menos dois dígitos). Vamos aplicar o mesmo conceito à nossa ER de validação, lembrando que 1900 é divisível por 4, mas não é bissexto e que 00 é equivalente ao ano 2000.
var regex = /^((((0?[1-9]|1\d|2[0-8])\/(0?[1-9]|1[0-2]))|
 //28 para todos os meses
((29|30)\/(0?[13456789]|1[0-2]))|
 //29 e 30 para todos menos fevereiro
(31\/(0?[13578]|1[02])))
 //31 para jan, mar, mai, jul, ago, out e dez
\/((19|20)?\d\d))$|
((29\/0?2\/)
 //29 de fevereiro
((19|20)?(0[48]|[2468][048]|[13579][26])|(20)?00))$/;
E, finalmente, nossa ER está pronta. Só falta aplicá-la num código de validação:
function valida_data(element) {
 regex = /^((((0?[1-9]|1\d|2[0-8])\/(0?[1-9]|1[0-2]))|((29|30)\/(0?[13456789]|1[0-2]))|(31\/(0?[13578]|1[02])))\/((19|20)?\d\d))$|((29\/0?2\/)((19|20)?(0[48]|[2468][048]|[13579][26])|(20)?00))$/;

 resultado = regex.exec(element.value);
 if(!resultado) {
   fica_errado(element);
 }
 else {
   fica_certo(element);
 }
}//fim da função
Sendo que fica_certo() e fica_errado() são funções que avisam o usuário de que a data está válida ou inválida, respectivamente. Essa função pode ser usada no evento onkeyup de um input type=text, por exemplo:
<input type="text" onkeyup="valida_data(this);" />
E pronto! Se quiser, veja um exemplo aqui. Como ERs podem ser aplicadas em várias linguagens de programação, você pode reaproveitá-la, provavelmente mudando apenas os escapes de caracteres. Fica aí a dica.
Clique e diga o que achou do café

URLs Amigáveis com o módulo Rewrite

Hoje em dia o a utilização de SEO é muito importante. Ainda mais com essa nova briga de motores de busca. E uma das dicas para melhorar a visibilidade é usar URLs que descrevam a página, em vez de códigos sem sentido. E isso também ajuda os visitantes. Você pode até pensar: "Se eu fizer isso, não posso mais usar os scripts de servidor", mas isso está completamente errado. É aí que entra o módulo Rewrite do Apache.

O módulo Rewrite reescreve uma URL baseado nos parâmetros que você definir. Assim, um link do tipo http://www.exemplo.com/noticia/1234 pode ser transformado em http://www.exemplo.com/noticias.php?id=1234 permitindo o uso de scripts personalizados.

Vamos ao lado prático da questão. Primeiro, temos que saber se o mod_rewrite está ativado no servidor. Para isso, basta dar uma olhada no phpinfo(). Caso não consiga encontrar, outra alternativa é usar o seguinte script:
<?php
  if (in_array("mod_rewrite",apache_get_modules())) {
  echo "Parabéns, o Módulo Rewrite está habilitado!";
} else {
  echo "Sinto muito, mas o Módulo Rewrite não foi habilitado :(";
}
?>
Se o servidor é seu (e você está usando linux) pode usar o comando
# a2enmod rewrite
para habilitar o módulo.

Para criar uma regra de redirecionamento, você precisa alterar o arquivo .htaccess na raiz do seu site ou em qualquer pasta que deseje utilizar o recurso. Caso o tal arquivo não exista, você podera criá-lo. É possível que o servidor impeça a utilização desse arquivo, mas em geral ele é permitido. Enfim, adicione as seguintes linhas no arquivo .htaccess:
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ script.php?redir=$1
A primeira linha habilita o módulo Rewrite no diretório em questão. A segunda evita que a regra se aplique a arquivos que existam fisicamente. A terceira é idêntica à segunda, mas diz respeito aos diretórios ao invés de arquivos. E a última é a regra propriamente dita, que redireciona qualquer texto após o diretório do .htaccess para script.php, enviando o texto na variável redir. Assim, uma URL http://www.exemplo.com/noticia/1234 será enviado para http://www.exemplo.com/script.php?redir=noticia/1234. Lembrando que isso não é um "redirecionamento" e sim uma renomeação de URL, os navegadores e motores de busca abrem a página como se ela estivesse fisicamente em http://www.exemplo.com/noticia/1234.

Outro exemplo é o caso de alteração de domínio. Caso você mude do www.exemplo.provedor.com para www.exemplo.com, você poderia criar um script no index.php do tipo:
<?php
header("HTTP/1.1 301 Moved Permanently");
header("location:http://www.exemplo.com");
exit;
?>
Isso é válido, mas se alguem acessar a URL http://www.exemplo.provedor.com/noticia/1234 simplesmente receberia um erro 404 de página não encontrada. Para evitar isso, usa-se o módulo Rewrite, usando a seguinte regra no .htaccess:
RewriteEngine On
RewriteRule (.*) http://www.exemplo.com/$1 [R=301,L]
Essa regra envia, por exemplo, a URL http://www.exemplo.provedor.com/noticia/1234 para http://www.exemplo.com/noticia/1234, ainda enviando o código 301 de redirecionamento permanente, informando aos navegadores, caches e mecanismos de busca, que este site mudou de endereço.

Mais informações sobre o módulo Rewrite pode ser encontrado na documentação do Apache em http://httpd.apache.org/docs/2.2/rewrite.

Fontes: Clube PC - Ativando o mod_rewrite. Servidores Linux, Guia Prático: mod_rewrite.
Clique e diga o que achou do café

Código com Café

Código sempre combina com café, não é à toa que temos o Java. Então, escolhi este nome para o blog que criei para compartilhar meus conhecimentos na área de programação. O conteúdo do blog dependerá principalemente da linguagem (ou linguagens) que eu estiver estudando atualmente. Além de código de fato, novidades na área e outras curiosidades podem também estarem presentes. Desejo um bom café para você, assine o feed e me diga o que acho nos comentários. Até mais!
Clique e diga o que achou do café