Nessa semana que culminará na 2ª edição do InterCon WP, me sinto instigado a escrever a respeito de um assunto talvez um pouco desconhecido pela maioria, mas que mais cedo ou mais tarde você poderá se deparar.
Dias atrás tive a necessidade de um usuário com a role Editor inserir um iframe diretamente no conteúdo de um post. Porém, ao realizar o salvamento, o código html do iframe era automaticamente excluído pelo WordPress. Na verdade, trata-se de um comportamento normal da plataforma, mas para usuários com as roles abaixo de Editor. Essa permissão, de salvar qualquer tipo de html em um post, é controlada pelo WordPress através da capability unfiltered_html, que por padrão é liberada nas roles de Administrador e Editor, exceto em uma instalação multisite, onde somente usuários com a liberação de Super Admin podem inserir esse tipo de conteúdo em um post.
A primeira abordagem, que funcionaria em uma instalação normal do WordPress para qualquer tipo de usuário, foi instalar um plugin de gerenciamento de Roles e Capabilities, como o WP Members, e fazer a liberação da capability unfiltered_html para a role Editor. Mas como estamos falando de uma instalação multisite do WordPress, isso não foi o suficiente para resolver a questão.
Pesquisando um pouco mais a fundo no core do WordPress, cheguei à função map_meta_cap() que faz o mapeamento de meta capabilities para capabilities primitivas da plataforma. Em uma condicional dentro dessa função encontraremos a seguinte lógica:
case 'unfiltered_html' : // Disallow unfiltered_html for all users, even admins and super admins. if ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML ) $caps[] = 'do_not_allow'; elseif ( is_multisite() && ! is_super_admin( $user_id ) ) $caps[] = 'do_not_allow'; else $caps[] = $cap; break;
Notem que a primeira condicional nos apresenta uma constante, DISALLOW_UNFILTERED_HTML, que podemos utilizar no arquivo wp-config.php e desabilitar a inclusão de códigos html e javascript para todos os usuários. A segunda condicional é justamente o que nos trava em uma instalação multisite do WordPress, não adianta a role do usuário ter a capability unfiltered_html, se ele não for um Super Admin, não conseguirá incluir esse tipo de conteúdo.
Para “burlar” esse comportamento padrão e permitir que os usuários com a role Editor conseguissem salvar o post com o iframe no seu conteúdo utilizei o hook map_meta_cap, liberando através de uma função no tema a capability unfiltered_html.
add_filter( 'map_meta_cap', 'map_unfiltered_html', 99, 4 ); function map_unfiltered_html( $caps, $cap, $user_id, $args ) { $user = get_userdata( $user_id ); if ( ( 'editor' == $user->roles[0] ) and ( 'unfiltered_html' == $cap ) ) : $caps = array( $cap ); endif; return $caps; }
Esse hook map_meta_cap é muito poderoso e útil para trabalhar as permissões de um usuário dentro do nosso projeto WordPress, mas cuidado com seu uso, certifiquem-se sempre se a liberação que estão dando está indo somente para os usuários desejados, caso contrário podemos criar grandes brechas de segurança em nossos plugins ou temas.
Para aprender mais sobre as Roles e Capabilites do WordPress visite o artigo do Codex que fala a respeito. E nunca se esqueça de usar o core da plataforma como aliado a seus estudos, muita coisa vamos passar a entender realmente como funciona só depois de uma boa olhada no código fonte.
Não percam o InterCon WP 2014, o maior evento técnico de WordPress da América Latina, no próximo sábado, dia 31/05. Nos vemos lá.