Arquivo mensais:março 2012

O sonho americano dos que mal dormem

Lá por volta de 2007, na época em que saiu, assisti À Procura da Felicidade (The Pursuit of Happyness) em Santa Catarina. Na ocasião, minha impressão sobre o filme não foi boa e, com efeito, na minha memória não restava nada de positivo sobre ele. Me incomodou muito a mensagem do roteiro, algo como “não importa quão ferrado você está; se esforçando e acreditando nos seus sonhos você só depende de você para subir na vida”.

Inspirado pela ideia de assistir filmes que se passam em San Francisco e particularmente por ter visto um cartaz de um músico de rua na Chinatown dizendo que ele apareceu no filme, resolvi encará-lo novamente na semana passada. Dessa vez, achei tão brilhante que me vejo obrigado a escrever esta nota, que quero compartilhar com meus amigos no Brasil, para recomendá-lo.

“À Procura da Felicidade”, para muito além dessa mensagem e das belas imagens, e embora se passe na década de 80, é um fantástico retrato de uma característica muito atual da San Francisco que estou conhecendo nas oportunidades que tenho de visitá-la: uma cidade de sem-tetos, cada um por si à procura da sua felicidade. Não se trata de um problema só de San Francisco (alguém poderia argumentar que as pessoas vivem na rua lá porque é a cidade dos hippies — if you’re going to San Francisco, be sure to wear some flowers in your hair), mas de um problema que salta aos olhos nas grandes cidades dos Estados Unidos (em especial na Califórnia) e que neste país, onde a realidade dos 99% dificilmente tem dinheiro pra passar na TV, parece não ser muito divulgado e muito menos combatido da forma que deveria.

Em um estudo realizado com dados de 2005 e 2006, concluiu-se que todo ano uma a cada cinquenta crianças dos Estados Unidos encara não ter casa. Já seria absurdo, mas esse número hoje (pós-crise) é com certeza bem maior, já que várias pessoas têm perdido suas casas desde 2008. Camaradas que conheci da ISO do norte da Califórnia, que são ativistas em movimentos de moradia por aqui, estimam que 50 milhões (i.e., 1/6 de uma população de cerca de 300 milhões) já passaram pela experiência de ficarem sem teto.

Diferente de como funcionam as coisas no nosso país, aqui o governo não permite construções irregulares (tipo as nossas favelas). Como resultado, o que vemos é algumas pessoas vivendo em abrigos, algumas revezando casas de amigos, algumas nos seus carros, algumas acampadas (principalmente pós-2008), muitas nas prisões (0.7% da população dos Estados Unidos está presa neste momento e o número quadruplica se você considerar liberdades condicionais e pessoas em observação: é o recorde mundial) e muitas simplesmente nas ruas mesmo. Os abrigos são muito insuficientes para a quantidade de pessoas sem teto: em San Francisco, há uma vaga para cada quinze pessoas sem lugar para morar. Na maioria dos lugares, é preciso conquistar diariamente uma vaga.

Estou numa tentativa de falar com o máximo de pessoas que consigo para aprender sobre essa gente. Esses dias, pegando um trem, puxei conversa com um homem muito sujo, com sotaque muito engraçado (para mim) e com uma mochila, negro, velho, não me lembro o nome. Acho que ele gostou de mim: repetiu várias vezes que eu era louco, mas foi me contando várias coisas. Depois de trocarmos ideias descobri que era veterano do Vietnã. Falei pra ele que eu queria conhecer Oakland. Ele respondeu pra eu não ir, porque, nas suas palavras, “é uma cidade muito perigosa: muitos negros e sem-teto. Há muitos sem-teto aqui. Você não vê todos porque eles se escondem para não serem presos e você nem percebe que um é quando conversa com ele. Você com essa barba poderia ser um.”.

Sem entrar na discussão sobre outros problemas latentes como o racismo e a segregação, a falta de saúde, a falta de qualidade e o alto preço da educação, e a inércia dos que ainda acreditam no sonho americano e buscam [com necessidade e razão, mas usualmente em vão] individualmente a felicidade diante disso tudo, para não escrever um texto muito grande quero registrar apenas que estou há quase um mês e meio aqui e ainda me impressiono: é incrível o nível de desigualdade e de desumanidade que noto a cada minuto no país-modelo do capitalismo e na região do tão rico e inovador Vale do Silício.

A minha ideia, antes de vir pra cá, era que aqui as pessoas tivessem mais condições, que houvesse mais acesso a qualquer coisa que não só fast-food e gadgets de segunda linha: afinal, me parecia que o ganancioso capitalismo estadounidense já explora suficientemente o terceiro mundo. De fato, há muitas coisas bonitas e muito dinheiro aqui. No entanto, o dinheiro é muito concentrado e neste momento não acho que a vida dos 99% aqui seja tão melhor do que a vida dos 99% na América Latina. Talvez pela crise, pelo poder da propaganda, pelo individualismo ao qual são levados pela fé num sistema que os explora sem parar, pela aparente dificuldade de luta organizada e pela ausência de organizações de esquerda com influência de massas na história recente, seja o contrário. De qualquer forma, cada vez tenho mais certeza de que aqui e aí temos, entre outras coisas, um grande desafio em comum. A construção de outro futuro, que reinvente as relações humanas, no qual tenhamos igualdade e democracia de verdade é uma necessidade urgente e internacional.

Publicado originalmente no Juntos.

WordPress plugin: Admin Anti-forget Alarm

I wrote a small WordPress plugin to prevent users from publishing a post without excerpt or thumbnail, or with a too big excerpt, or with a too small thumbnail, or with an uppercase-only title.

This screenshot is showing some of the messages the plugin displays in portuguese.

For some of my websites it’s important to require the editors to fix some stuff before publishing something, and it looks like this is a useful feature for other people as well. There is even a Require Thumbnail plugin in the WordPress Plugin Directory that seems to do one of the things I’ve just implemented.

The plugin works with two different types of requirements: ths first generates errors (i.e., you can’t publish if you don’t fix it) and the second generates warnings (i.e., you will receive a message but you can proceed to publish if you really want to do that).

I thought of not releasing the plugin (because it’s written in Portuguese and you don’t have a cool interface to decide what’s required yet), but in a fashion of overstated bazaar I decided to push the code anyway (without putting in the WordPress plugin directory, of course) so that other people can collaborate if they want to. Take a look :)

Github project home page: https://github.com/tmadeira/antiforget
Git repository to clone: https://github.com/tmadeira/antiforget.git
Code (PHP): https://github.com/tmadeira/antiforget/blob/master/antiforget.php
Download: antiforget.zip (this is pre-alpha: I provide no warranty!)

Como mostrar o último post de cada categoria no WordPress?

O WordPress é um dos meus programas preferidos e um dos que mais consome as madrugadas já faz alguns anos. Escrevi inúmeros temas, alguns plugins (um único genérico o suficiente para ser público) e já modifiquei algumas partes do código (embora hoje seja raro isso ser necessário).

Acho muito simples e me divirto ao programar em PHP para a web (talvez porque eu faça isso há uns dez anos). Gosto muito da forma como o WordPress é escrito e, com efeito, seu lema é Code is poetryCódigo é poesia. Sua documentação e seu código são muito didáticos e foram, assim como seus temas e as tabelas no banco de dados, evoluindo de acordo com o tempo: as atualizações sempre têm novas features e formas mais genéricas e mais elegantes de fazer as coisas.

O WordPress é um software livre usado por mais de 15% da web (um número incrível!) e tem uma comunidade que produz várias extensões (temas e plugins). Gosto tanto dele que certa vez (no final de 2007) escrevi um plugin só para ganhar uma camiseta (que é tamanho G e ainda assim uso de vez em quando).

Propaganda e blogagem a parte, me deparei com um problema interessante em um dos sites que administro com ele no último fim de semana (a gente sempre se depara com problemas interessantes no WordPress também): dado uma categoria com várias subcategorias, gostaria de mostrar um link para o último post de cada uma de suas subcategorias na página inicial.

Uma solução trivial seria fazer uma query pedindo os filhos de uma dada categoria (usando a tabela wp_term_taxonomy) e uma query por categoria para descobrir seu último post (usando as tabelas wp_posts e wp_term_relationships). Suponha (até o final desse post) que a categoria-mãe de todas as categorias que eu quero mostrar na página seja a de ID 33. Então, essa solução seria algo como:

<?php
$query = mysql_query("SELECT term_id FROM wp_term_taxonomy
                      WHERE parent = 33 AND taxonomy = 'category'");
while (list($cid) = mysql_fetch_row($query)) {
    $posts_query = mysql_query("SELECT p.ID, p.post_name, p.post_title
                                FROM wp_posts AS p,
                                     wp_term_relationships AS r
                                WHERE p.ID = r.object_ID AND r.term_taxonomy_id = '$cid'
                                ORDER BY p.post_date DESC
                                LIMIT 1");
    if (mysql_num_rows($posts_query)) {
        list($id, $permalink, $title) = mysql_fetch_row($posts_query);
        // Faça o que quiser com o post aqui
    } else {
        echo "A categoria $cid não tem posts.\n";
    }
}
?>

Não deve ser difícil de entender, mas dá pra resolver de forma ainda mais simples que essa. O WordPress é fantástico e usar as funções dele próprio é bem mais simples, genérico e resolve o problema. A função get_categories aceita um monte de parâmetros, mas só precisamos do child_of:

<?php
foreach (get_categories('child_of=33') as $cat) {
    list($post) = get_posts("numberposts=1&category={$cat->term_id}");
    // Faça o que quiser com o post aqui
}
?>

(quem entrou no post procurando a solução pro problema pode parar por aqui se não for nerd)

Porém, eu queria resolver o problema com uma única query. Achei que seria mais elegante resolver o problema todo no banco de dados sem escrever em PHP e achei que poderia ficar mais rápido. Acho que não ficou mais elegante e não faço ideia se fica mais rápido (fiquei com a impressão de que seja pior porque faço JOIN de quatro tabelas enormes), nem acho que tenha volume de dados (ainda) no site em que implementei isso pra realmente me preocupar, mas me diverti fazendo. Então segue o resultado:

SELECT p.ID AS id,
       CASE WHEN (p.post_date > DATE_SUB(CURDATE(), INTERVAL 1 MONTH)) THEN
           p.post_title
       ELSE
           ''
       END AS title,
       GROUP_CONCAT(c.slug) AS cat
FROM wp_posts AS p
INNER JOIN
    (
        SELECT MAX(p.post_date) AS post_date, c.term_ID AS cid, COUNT(p.ID) AS count FROM
            wp_posts AS p,
            wp_term_relationships AS r,
            wp_terms AS c
        WHERE
            p.ID = r.object_ID AND
            c.term_ID = r.term_taxonomy_ID AND
            p.post_status = 'publish' AND
            p.post_type = 'post'
        GROUP BY c.term_id
    ) AS last ON p.post_date = last.post_date
INNER JOIN wp_term_relationships AS r ON p.ID = r.object_ID
INNER JOIN wp_terms AS c ON c.term_id = r.term_taxonomy_ID
INNER JOIN wp_term_taxonomy AS t ON t.term_id = r.term_taxonomy_ID
WHERE
    c.term_id = last.cid
    AND t.parent = 33
    AND t.taxonomy = 'category'
    AND p.post_status = 'publish'
    AND p.post_type = 'post'
    # AND last.count >= 3
GROUP BY p.ID ORDER BY p.post_date DESC, last.count DESC;

A query (que na verdade é duas) ordena o resultado por data, retorna o título vazio caso o post seja de mais de um mês atrás, junta as categorias (separando-as por vírgula) se um mesmo post for o último de mais de uma categoria e neste caso ordena as categorias por ordem decrescente de número de posts na mesma.

(A parte comentada seria para caso eu só quisesse mostrar o último post de categorias com três ou mais posts.)

Usei o resultado da query da seguinte forma:

$q = mysql_query($query); // $query é a string com aquele SQLzão
$print_final_li = false;
$first = true;
while ($a = mysql_fetch_array($q, MYSQL_ASSOC)) {
    echo "\t\t<li>";
    $permalink = get_permalink($a["id"]);
    $title = $a["title"];
    if ($title == "") {
        $print_final_li = true;
        echo "Veja também: ";
    } else if ($first == true) {
        echo "<a href="$permalink" title="$title">";
        echo get_the_post_thumbnail($a["id"], "home-thumbnail",
                                    Array("title" => get_the_title()));
        echo "</a> ";
        $first = false;
    }
    $cats = explode(",", $a["cat"]);
    foreach ($cats as $low) {
        $up = strtoupper($low);
        echo "<a class="cat" href="http://$low.juntos.org.br/"
                 title="Juntos! $up">$up</a> ";
    }
    if ($print_final_li) break;
    echo "<a class="post" href="$permalink" title="$title">$title</a>";
    echo "</li>\n";
}
while ($a = mysql_fetch_array($q, MYSQL_ASSOC)) {
    $cats = explode(",", $a["cat"]);
    foreach ($cats as $low) {
        $up = strtoupper($low);
        echo "<a class="cat" href="http://$low.juntos.org.br/"
                 title="Juntos! $up">$up</a> ";
    }
}
if ($print_final_li) {
    echo "</li>\n";
}

(e se você quiser vê-lo em prática, entre em juntos.org.br e procure por “Juntos pelo Brasil”)

Não ficou bonitinho? Se por um lado gostei da solução, por outro fiquei imaginando que deva ser um SQL tremendamente ingênuo e digno da minha inexperiência com grandes bancos de dados. O que você acha? Consegue pensar numa forma mais simples, mais eficiente e mais elegante de resolver o mesmo problema? Ou ao menos sem subqueries?

Acho que as relações necessárias já ficaram explícitas na query que eu escrevi, mas segue o diagrama do banco de dados do WordPress pra quem precisar: