Permitir posts por usuários no WordPress (ou qualquer conteúdo) sem que seja necessário login, não é uma tarefa muito complicada. De fato, também existe uma função, chamada de wp_insert_post, que serve exatamente para isso, assim como existe uma função para praticamente tudo no CMS.

O problema da função wp_insert_post é que ela insere o conteúdo sem verificar nada, você só precisa dizer quais os valores que serão enviados e ela fará o resto para você. Com isso, não teremos verificações nem coisas do tipo.

Neste artigo você verá como criar um formulário e tratar os valores para que os usuários tenham a possibilidade de enviar conteúdo para seu blog. Como cada pessoa vai precisar de uma coisa específica, vou criar um plugin genérico como base para seu desenvolvimento. Tudo muito simples e direto. Você fará o restante conforme precisar.

Criando um plugin

Já explicamos como criar um plugin do WordPress aqui no Tutsup, portanto, se ainda não viu tal tutorial, segue o link:

Para nosso objetivo, crie uma pasta dentro de wp-content/plugins chamada de tutsup-posts-usuarios.

Pasta do nosso plugin

Pasta do nosso plugin

Dentro dessa pasta, crie um arquivo chamado de tutsup-posts-usuarios.php com o seguinte conteúdo:

<?php
/* 
Plugin Name: Tutsup Posts Usuários
Plugin URI: http://www.todoespacoonline.com/w/
Description: Permite envio de posts por usuários.
Version: 0.0.1
Author: Luiz Otávio Miranda
Author URI: http://www.todoespacoonline.com/w/
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
*/

Esses são os dados do nosso plugin, você pode modificar conforme preferir.

Ative o plugin pelo painel administrativo do WordPress.

Classe do nosso plugin

Dentro do arquivo do nosso plugin, vamos trabalhar com classes PHP (PHP Orientado a Objetos). Se você ainda não tem experiência com OOP, segue um tutorial de introdução e o nosso curso básico:

Primeiramente vamos verificar se a classe existe, em seguida vamos criar a classe e carregar a mesma, veja:

/**
 * TpPostsUsuarios
 *
 * Essa é a classe geral do nosso plugin
 */
if ( ! class_exists('TpPostsUsuarios') ) {

	class TpPostsUsuarios
	{
    
            // MÉTODOS VIRÃO AQUI
     
	} // TpPostsUsuarios
	
	/* Loads the class */
	$TutsupContato = new TpPostsUsuarios();
    
} // class_exists('TpPostsUsuarios')

Vamos trabalhar na parte “MÉTODOS VIRÃO AQUI” da classe, onde criaremos todas as propriedades e métodos necessários para o nosso plugin.

Propriedade de erro

Vamos criar uma propriedade estática dentro da nossa classe para manter os erros. Por erros, quero dizer algo que o usuário tenha feito de maneira incorreta, como não preencher todos os campos e coisas do tipo.

Para criar uma propriedade estática, faça o seguinte:

/*
 * Caso ocorra um erro, utilizaremos esta propriedade para exibi-lo
 */
public static $erro;

Ao decorrer da classe, vamos preenchendo essa propriedade de acordo com o tempo que os erros vão ocorrendo.

Caso ocorra algum erro, não enviaremos os dados para o WordPress, apenas exibiremos o erro dentro do formulário para o usuário.

Método construtor

O método construtor de uma classe PHP é carregado assim que ela for instanciada, isso quer dizer que ele carregará o que precisarmos assim que o plugin for ativado no WordPress.

Para nosso método construtor, vamos carregar dois outros métodos:

  • registra_posts_usuarios – Vamos registrar um Custom Post Type específico para posts dos usuários;
  • envia_dados – Vamos registrar este método para receber os dados enviados pelo usuário para que possamos validar os campos.

Veja como ficou nosso método construtor:

/**
 * Construtor da classe
 * 
 * Carrega todos os métodos que precisamos ao instanciar a classe.
 */
public function __construct() {
    add_action( 'init', array( $this, 'registra_posts_usuarios' ) );
    add_action( 'parse_request', array( $this, 'envia_dados' ) );
}

Agora precisamos criar os métodos que estamos carregando dentro do construtor.

Método registra_posts_usuarios

Este método será responsável por criar o Custom Post Type específico para os posts enviados pelos usuários, veja:

/**
 * Registra um custom post type exclusivo para os usuários
 */
public function registra_posts_usuarios() {
    $labels = array(
        'name'               => 'Posts externos',
        'singular_name'      => 'Post externo',
        'menu_name'          => 'Posts externos',
        'name_admin_bar'     => 'Posts externos',
        'add_new'            => 'Novo',
        'add_new_item'       => 'Novo',
        'new_item'           => 'Novo',
        'edit_item'          => 'Editar',
        'view_item'          => 'Visualizar',
        'all_items'          => 'Posts externos',
        'search_items'       => 'Encontrar',
        'parent_item_colon'  => 'Pais:',
        'not_found'          => 'Nada encontrado.',
        'not_found_in_trash' => 'Nada encontrado.',
    );
     
    $args = array(
        'labels'             => $labels,
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'query_var'          => true,
        'capability_type'    => 'post',
        'has_archive'        => true,
        'hierarchical'       => false,
        'menu_position'      => null,
        'rewrite'            => array('slug' => '_tp_posts_externos'),
        'can_export'         => true,
        /*'taxonomies'         => array('post_tag'),*/
        'supports'           => array(
            'title',
            'editor',
            'author',
            /*'thumbnail',*/  
            /*'excerpt',*/
            /*'trackbacks',*/
            /*'custom-fields',*/
            /*'comments',*/
            /*'revisions',*/
            /*'page-attributes',*/
            /*'post-formats'*/
        ),
    );
     
    // Registra o custom post
    register_post_type( '_tp_posts_externos', $args );        
}

Veja que existem várias coisas comentadas no Custom Post Type acima, são coisas que não vou precisar, mas você pode remover os comentários se preferir.

Isso deverá criar o seguinte no painel administrativo do WordPress.

Nosso Custom Post Type

Nosso Custom Post Type

Os dados enviados por usuários estarão dentro desse Custom Post.

Método envia_dados

Este método é responsável por receber os dados enviados pelo formulário que vamos criar. Como você vai perceber, toda a validação dos campos será adicionada nele.

/**
 * Este método irá receber os dados enviados pelo formulário
 */
public function envia_dados () {
    
    /* Verifica se os dados do formulário foram enviados */
    if ( 
        'POST' != $_SERVER['REQUEST_METHOD'] 
        || ! isset( $_POST['_tp_titulo'] )
        || ! isset( $_POST['_tp_conteudo'] )
    ) {
        return;
    }

    // Configura o post para uma variável
    $dados = $_POST;
    
    // Título
    $titulo = !empty($dados['_tp_titulo']) ? $dados['_tp_titulo'] : null;
    $titulo = sanitize_text_field($titulo);
    
    // Conteúdo
    $conteudo = !empty($dados['_tp_conteudo']) ? $dados['_tp_conteudo'] : null; 
    
    // Verifica se os campos tem algum valor
    if ( ! $titulo || ! $conteudo ) {
        self::$erro = 'Você deve preencher todos os campos!';
        return;
    }
    
    // Verifica o campo nonce
    if ( 
        ! isset( $_POST['tutsup_posts_nonce'] ) 
        || ! wp_verify_nonce( $_POST['tutsup_posts_nonce'], 'tutsup_posts_usuarios' ) 
    ) {
        self::$erro = 'Erro ao enviar formulário!';
        return;
    }
    
    // Cria os dados do post
    $dados_post = array(
      'post_title'    => $titulo, // Título do post
      'post_content'  => $conteudo, // Conteúdo do post
      'post_status'   => 'pending', // Status do post
      'post_type'     => '_tp_posts_externos', // Tipo do post
      'post_author'   => 2 // Autor do post
    );

    // Tenta inserir o post
    $post_id = wp_insert_post( $dados_post );

    // Se o post for inserido com sucesso, teremos o ID do mesmo
    if ( ! $post_id ) {
        self::$erro = 'Erro ao enviar post!';
        return;
    }
}

O método acima deverá estar ligado diretamente ao formulário que iremos criar posteriormente, pois, campos validados acima serão enviados por tal formulário.

Se você precisar de mais valores no Custom Post, analise a função wp_insert_post. Caso precise de meta dados para os posts, utilize o ID retornado após o post ser criado.

Método formulário

Este método é simplesmente um formulário HTML que podemos inserir em qualquer parte do nosso tema.

/**
 * Este é um formulário HTML muito básico
 */
public function formulario() {
    
    // Variável temporária para nosso erro
    $erro = null;
    
    // Verifica se existe algum erro e exibe
    if ( self::$erro ) {
        $erro = '<p>' . self::$erro . '</p>';
    } 
    // Se não houver erros e o formulário foi enviado, o post foi
    // Inserido com sucesso
    elseif (
        ! self::$erro 
        && isset( $_POST['_tp_titulo'] ) 
        && isset( $_POST['_tp_conteudo'] ) 
    ) {
        $erro = '<p>Dados enviados com sucesso!</p>';
    }
    ?>
    
    <form action="" method="post">
    
    <p>
        Título:<br>
        <input type="text" value="<?php 
        echo esc_attr(stripslashes(@$_POST['_tp_titulo']));
        ?>" name="_tp_titulo">
    </p>
    
    <p>
        Conteúdo:<br>
        <textarea name="_tp_conteudo"><?php 
        echo esc_attr(stripslashes(@$_POST['_tp_conteudo']));
        ?></textarea>
    </p>
    
    <p>
        <?php
        // Mostra o erro (se não houver um erro, mostra nada)
        echo $erro;
        
        // Adiciona nosso campo nonce
        wp_nonce_field('tutsup_posts_usuarios', 'tutsup_posts_nonce');
        ?>
        <input type="submit" value="Enviar">
    </p>
    
    </form>
    
    <?php
}

Este método é responsável pelo nosso formulário, ou seja, o que será exibido para o usuário. O campo “nonce” é responsável pela segurança dos dados enviados pelo nosso formulário, isso significa que nossa classe apenas validará os campos, se o campo nonce vier do nosso formulário, nenhum outro.

Nosso plugin completo

Veja como ficou os dados do nosso plugin:

<?php
/* 
Plugin Name: Tutsup Posts Usuários
Plugin URI: http://www.todoespacoonline.com/w/
Description: Permite envio de posts por usuários.
Version: 0.0.1
Author: Luiz Otávio Miranda
Author URI: http://www.todoespacoonline.com/w/
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
*/

/**
 * TpPostsUsuarios
 *
 * Essa é a classe geral do nosso plugin
 */
if ( ! class_exists('TpPostsUsuarios') ) {

	class TpPostsUsuarios
	{
        
        /*
         * Caso ocorra um erro, utilizaremos esta propriedade para exibi-lo
         */
        public static $erro;
		
        /**
         * Construtor da classe
         * 
         * Carrega todos os métodos que precisamos ao instanciar a classe.
         */
		public function __construct() {
            // Registra um custom post exclusivo para os usuários
            add_action( 'init', array( $this, 'registra_posts_usuarios' ) );
            add_action( 'parse_request', array( $this, 'envia_dados' ) );
		}
        
        /**
         * Registra um custom post type exclusivo para os usuários
         */
        public function registra_posts_usuarios() {
            $labels = array(
                'name'               => 'Posts externos',
                'singular_name'      => 'Post externo',
                'menu_name'          => 'Posts externos',
                'name_admin_bar'     => 'Posts externos',
                'add_new'            => 'Novo',
                'add_new_item'       => 'Novo',
                'new_item'           => 'Novo',
                'edit_item'          => 'Editar',
                'view_item'          => 'Visualizar',
                'all_items'          => 'Posts externos',
                'search_items'       => 'Encontrar',
                'parent_item_colon'  => 'Pais:',
                'not_found'          => 'Nada encontrado.',
                'not_found_in_trash' => 'Nada encontrado.',
            );
             
            $args = array(
                'labels'             => $labels,
                'public'             => true,
                'publicly_queryable' => true,
                'show_ui'            => true,
                'show_in_menu'       => true,
                'query_var'          => true,
                'capability_type'    => 'post',
                'has_archive'        => true,
                'hierarchical'       => false,
                'menu_position'      => null,
                'rewrite'            => array('slug' => '_tp_posts_externos'),
                'can_export'         => true,
                /*'taxonomies'         => array('post_tag'),*/
                'supports'           => array(
                    'title',
                    'editor',
                    'author',
                    /*'thumbnail',*/  
                    /*'excerpt',*/
                    /*'trackbacks',*/
                    /*'custom-fields',*/
                    /*'comments',*/
                    /*'revisions',*/
                    /*'page-attributes',*/
                    /*'post-formats'*/
                ),
            );
             
            // Registra o custom post
            register_post_type( '_tp_posts_externos', $args );        
        }
        
        /**
         * Este método irá receber os dados enviados pelo formulário
         */
        public function envia_dados () {
            
            /* Verifica se os dados do formulário foram enviados */
            if ( 
                'POST' != $_SERVER['REQUEST_METHOD'] 
                || ! isset( $_POST['_tp_titulo'] )
                || ! isset( $_POST['_tp_conteudo'] )
            ) {
                return;
            }
        
            // Configura o post para uma variável
            $dados = $_POST;
            
            // Título
            $titulo = !empty($dados['_tp_titulo']) ? $dados['_tp_titulo'] : null;
            $titulo = sanitize_text_field($titulo);
            
            // Conteúdo
            $conteudo = !empty($dados['_tp_conteudo']) ? $dados['_tp_conteudo'] : null; 
            
            // Verifica se os campos tem algum valor
            if ( ! $titulo || ! $conteudo ) {
                self::$erro = 'Você deve preencher todos os campos!';
                return;
            }
            
            // Verifica o campo nonce
            if ( 
                ! isset( $_POST['tutsup_posts_nonce'] ) 
                || ! wp_verify_nonce( $_POST['tutsup_posts_nonce'], 'tutsup_posts_usuarios' ) 
            ) {
                self::$erro = 'Erro ao enviar formulário!';
                return;
            }
            
            // Cria os dados do post
            $dados_post = array(
              'post_title'    => $titulo, // Título do post
              'post_content'  => $conteudo, // Conteúdo do post
              'post_status'   => 'pending', // Status do post
              'post_type'     => '_tp_posts_externos', // Tipo do post
              'post_author'   => 2 // Autor do post
            );

            // Tenta inserir o post
            $post_id = wp_insert_post( $dados_post );

            // Se o post for inserido com sucesso, teremos o ID do mesmo
            if ( ! $post_id ) {
                self::$erro = 'Erro ao enviar post!';
                return;
            }
        }
        
        /**
         * Este é um formulário HTML muito básico
         */
        public function formulario() {
            
            // Variável temporária para nosso erro
            $erro = null;
            
            // Verifica se existe algum erro e exibe
            if ( self::$erro ) {
                $erro = '<p>' . self::$erro . '</p>';
            } 
            // Se não houver erros e o formulário foi enviado, o post foi
            // Inserido com sucesso
            elseif (
                ! self::$erro 
                && isset( $_POST['_tp_titulo'] ) 
                && isset( $_POST['_tp_conteudo'] ) 
            ) {
                $erro = '<p>Dados enviados com sucesso!</p>';
            }
            ?>
            
            <form action="" method="post">
            
            <p>
                Título:<br>
                <input type="text" value="<?php 
                echo esc_attr(stripslashes(@$_POST['_tp_titulo']));
                ?>" name="_tp_titulo">
            </p>
            
            <p>
                Conteúdo:<br>
                <textarea name="_tp_conteudo"><?php 
                echo esc_attr(stripslashes(@$_POST['_tp_conteudo']));
                ?></textarea>
            </p>
            
            <p>
                <?php
                // Mostra o erro (se não houver um erro, mostra nada)
                echo $erro;
                
                // Adiciona nosso campo nonce
                wp_nonce_field('tutsup_posts_usuarios', 'tutsup_posts_nonce');
                ?>
                <input type="submit" value="Enviar">
            </p>
            
            </form>
            
            <?php
        }
        
	} // TpPostsUsuarios
	
	/* Loads the class */
	$TutsupContato = new TpPostsUsuarios();
    
} // class_exists('TpPostsUsuarios')

Isso ainda não permite recebermos posts por usuários no WordPress, ainda precisamos chamar o nosso formulário dentro do tema.

Editando seu tema

Em qualquer parte do seu tema (fora do loop), adicione o seguinte:

<?php
if ( class_exists('TpPostsUsuarios') ) {
    $posts_usuarios = new TpPostsUsuarios();
    
    echo $posts_usuarios->formulario();
}
?>

Isso deverá exibir o formulário para o usuário enviar os posts.

Nosso formulário simples

Nosso formulário simples

Basta preencher e visualizar os dados na sua área administrativa.

Download do código

Caso queira baixar o plugin que criamos acima, utilize o link abaixo:

Instale, ative o plugin e adicione o seguinte no seu tema:

<?php
if ( class_exists('TpPostsUsuarios') ) {
    $posts_usuarios = new TpPostsUsuarios();
    
    echo $posts_usuarios->formulario();
}
?>

Edite conforme precisar!

Concluindo

Conforme descrevi no início do artigo, este plugin é uma base para que você conclua conforme suas necessidades. Não há nenhuma verificação de permissões de usuários ou coisas do tipo, portanto, você deve concluir essa operação.

Se você deseja tirar alguma dúvida, basta comentar aí abaixo.