Múltiplos botões "submit" em um formulário

22/11/06

A maioria das pessoas não sabe que é possível adicionar mais de um botão do tipo "submit". Mas se você precisa fazer algo como o Wordpress, pode ser uma mão na roda!

Múltiplos submits no Wordpress

Eu uso uma função em PHP que me ajuda bastante quando preciso fazer algo parecido.

<?php
function get_post_action($name)
{
    $params = func_get_args();
    
    foreach ($params as $name) {
        if (isset($_POST[$name])) {
            return $name;
        }
    }
}
?>

Ela é muito simples, mas extremamente útil. Basta passar os nomes possíveis dos botões e a função retornará qual a ação escolhida. Para usá-la, você pode fazer algo assim:

<?php
switch (get_post_action('save', 'submit', 'publish')) {
    case 'save':
        //save article and keep editing
        break;
    
    case 'submit':
        //save article and redirect
        break;
    
    case 'publish':
        //publish article and redirect
        break;
    
    default:
        //no action sent
}
?>

No seu HTML não precisa de muito. Apenas coloque o atributo name com os valores que você irá verificar.

<form method="post" action="form.php">
    <p>
        <input type="submit" name="save" value="Salvar e continuar editando" /> 
        <input type="submit" name="submit" value="Salvar" /> 
        <input type="submit" name="publish" value="Publicar" />
    </p>
</form>

E por favor, pare de mudar o atributo action do formulário através de Javascript.

PHP e SQL Injection

07/11/06

Estava explicando para um amigo meu porque não se deve interpolar uma variável direto no SQL. O grande problema é que ao fazer desta maneira, seu sistema fica suscetível a SQL Injection.

Imagine que você faça algo como abaixo.

<?php
$query = "SELECT name, email, password FROM table WHERE field='".$_GET['field']."' LIMIT 1";
?>

Se alguém passar no parâmetro algo como ' OR 1=1 #, seu banco ficaria totalmente exposto, pois a string final seria modificada com uma condição que será sempre satisfeita.

SELECT name, email, password FROM table WHERE field = '' OR 1=1 #' LIMIT 1

Parabéns! Alguém acabou de pegar todos os registros de sua tabela. Para evitar esse tipo de ataque, é aconselhável usar a função mysql_real_escape_string. Ela faz o devido escape de caracteres potencialmente inseguros. A desvantagem é que você tem que fazer isso para cada um dos parâmetros que você vai passar, o que pode se tornar um pouco massante.

Então, passei para ele uma função que eu usava há algum tempo atrás.

<?php
/**
 * @param string $query
 * @param mixed $arg1, $arg2...$argN 
 */
$QUERY = "";
function query($query)
{
    global $QUERY;
    
    $args = func_get_args();
    $query = array_shift($args);
    
    foreach ($args as $key => $arg) {
        if (is_string($arg)) {
            $args[$key] = mysql_real_escape_string($arg);
        }
    }
    
    array_unshift($args, $query);
    $query = call_user_func_array('sprintf', $args);
    $QUERY = $query;
    
    return mysql_query($query);
}
?>

Use a função acima da seguinte maneira:

<?php
$query = "SELECT name, email, password FROM table WHERE field='%s' LIMIT 1";
$resource = query($query, $_GET['field']);
 
while ($row = mysql_fetch_object($resource)) {
    printf('<strong>%s:</strong> %s<br/>', $row->name, $row->email);
}
?>

Você pode passar quantos parâmetros precisar, seguindo as regras da função sprintf.

<?php
$query = "INSERT INTO table (amount, age, name) VALUES (%.2f, %d, '%s')";
$resource = query($query, 150, 27, 'Nando Vieira');
?>

Uma outra vantagem de usar a função acima é que se você esquecer de passar algum parâmetro que estava esperando receber, um erro será exibido. E de quebra você ganha uma variável global $QUERY com a última instrução executada.

Wordpress e algumas coisas irritantes

14/10/06

O Wordpress é um dos melhores, se não o melhor, sistema de blogs da atualidade. Mas algumas coisas me irritam muito. Posso citar aqui de bate-e-pronto duas: a conversão de aspas e hífens. Se você posta códigos no seu blog, já deve ter enfrentado isso. Hoje fui postar um trecho de código que tinha aspas simples e dois hífens (parâmetro de um comando). O WP insistia em converte-los em entidades.

Fiquei de saco cheio e criei um plugin. Se você sofre dos problemas que eu falei, instale este plugin agora mesmo! Basta baixar o arquivo wp_coders.php e salvar na pasta "plugins". Depois, ative-o na seção "Plugins" do painel administrativo. Veja o código do plugin:

<?php
/*
Plugin Name: wp_coders
Plugin URI: http://simplesideias.com.br/wp-coders
Description: Removes WP annoyances (quotes and dashes)
Author: Nando Vieira
Version: 1.0
Author URI: http://simplesideias.com.br
*/
 
class wp_coders
{
    function wp_coders()
    {
        add_filter('comment_author', array(&$this, 'normalize'), 20);
        add_filter('comment_text', array(&$this, 'normalize'), 20);
        add_filter('bloginfo', array(&$this, 'normalize'), 20);
        add_filter('category_description', array(&$this, 'normalize'), 20);
        add_filter('list_cats', array(&$this, 'normalize'), 20);
        add_filter('the_content', array(&$this, 'normalize'), 20);
        add_filter('the_excerpt', array(&$this, 'normalize'), 20);
        add_filter('single_post_title', array(&$this, 'normalize'), 20);
        add_filter('the_title', array(&$this, 'normalize'), 20);
    }
 
    function normalize($text = '')
    {
        $text = str_replace(
            array('&#8212;', ' &#8212; ', '&#8211;'),
            array('---', ' -- ', '--'),
            $text
        );
        
        $text = str_replace(array("&#8216;", "&#8217;", "&#8242;"), "&#039;", $text);
        $text = str_replace(array("&#8220;", "&#8221;", "&#8243;"), "&#034;", $text);
        
        return $text;
    }
}
 
$wp_coders =& new wp_coders();
?>