Como tornar o plugin necessário em um tema wp sem usar instruções condicionais php ao chamar uma função individual desse plugin?

9

Um dos meus temas do Wordpress requer alguns plugins de terceiros para funcionar corretamente.

Na maioria das vezes, eu costumava chamar funções de plugins de terceiros usando instruções condicionais como

    if(function_exist('plugin_function')) {
             plugin_function() // do something
    }

suponha que eu precise usar extensivamente um plug-in através de muitos arquivos do meu tema ... Gostaria de evitar o uso de muitas condições SE ... existe uma maneira adequada de exigir que determinado plug-in específico seja instalado no WP ou melhor instalá-los se eles estiverem faltando antes de ativar o tema?

obrigado

unfulvio
fonte

Respostas:

7

is_plugin_active()é bastante frágil: será interrompido quando o autor do plugin renomear o arquivo principal ou quando o usuário renomeia o diretório ou o arquivo principal do plug-in. É melhor verificar se existe uma determinada função pública.

Para evitar fazer essa verificação sempre que precisar de algumas das funcionalidades do plug-in, você pode mostrar uma mensagem na área de administração:

add_action( 'admin_notices', 'my_theme_dependencies' );

function my_theme_dependencies() {
  if( ! function_exists('plugin_function') )
    echo '<div class="error"><p>' . __( 'Warning: The theme needs Plugin X to function', 'my-theme' ) . '</p></div>';
}

Outra alternativa é usar algo como http://tgmpluginactivation.com/

scribu
fonte
Se o autor do plug-in alterar um nome de função com o qual você questiona function_exists, um usuário normal simplesmente receberá a mensagem de que ele não instalou o plug-in em que outro plug-in se baseia. O problema é que o usuário realmente terá o plug-in instalado e então se pergunte por que ele não funciona . Ah, e eu não vou te rebaixar por isso.
precisa saber é o seguinte
Se você se importa com os votos, deve votar no próprio Q, pois ele é bom.
Kaiser
Se o autor do plugin alterar o nome da função, ele receberá reclamações de muito mais usuários do que se ele mudasse o nome do arquivo.
scribu
E diminuí a votação da sua resposta porque ela não abordou a questão, IMO. Ou você prefere que eu diminua o voto secretamente, sem nenhuma explicação?
scribu
Eu estava apenas falando sobre o voto negativo, não o comentário. O comentário em si está ok, pois esse tópico é algo que precisa ser discutido. Acrescentarei outra resposta, pois meus pensamentos por trás disso excederão o comprimento dos comentários. Apenas edite a resposta, para que possamos manter os resultados da discussão nas revisões para que todos possam seguir. Obrigado.
kaiser
1

Embora isso não impeça a quebra do tema quando o plug-in estiver desativado, consulte este artigo sobre o plug-in "Como exibir um aviso de administrador para os temas necessários" . Nunca me senti à vontade com a ideia de um tema que força a instalação de um plug-in, e essa parece ser a próxima melhor opção.

Outro pensamento rápido: nunca tentei isso, mas me pergunto se você poderia descobrir uma maneira inteligente de abrigar vários ganchos em uma única condicional. Talvez você possa separar todas as funções condicionais em um arquivo diferente e requerê-lo apenas se if( function_exists( 'plugin_function' ) )retornar true(com o entendimento de que essa é uma verificação imperfeita.

mrwweb
fonte
0

Se você precisar apenas de uma página de plug-in, então existe is_plugin_active(). Se você precisar do lado de fora, é melhor copiar / colar a função principal do seu tema e depois reutilizá-la:

if ( ! is_admin() )
{
/**
 * Check whether the plugin is active by checking the active_plugins list.
 *
 * @since 2.5.0
 *
 * @param string $plugin Base plugin path from plugins directory.
 * @return bool True, if in the active plugins list. False, not in the list.
 */
function is_plugin_active( $plugin ) {
    return in_array( $plugin, (array) get_option( 'active_plugins', array() ) ) || is_plugin_active_for_network( $plugin );
}
}

O condicional evita erros com a definição dupla da função.

kaiser
fonte
Isso realmente não responde à pergunta. Ele simplesmente substitui if(function_exist('plugin_function'))porif(is_plugin_active('plugin-file.php'))
scribu
0

Nota: Esta resposta está aqui apenas para facilitar a discussão entre @scribu e @kaiser. Mods: por favor, não exclua. Usuários / Leitores: Por favor, não vote. Se você deseja acompanhar a discussão, consulte o log de revisão / edição. Se você quiser participar da discussão, edite a resposta. Se a discussão tiver resultado, ela será marcada como tal. Obrigado.


Cenários

Também existem cenários diferentes com peso diferente, nos quais você pode ter uma dependência de plug-in. (Os exemplos são apenas fictícios). A palavra "(pai) Plugin" pode ser trocada com "Tema" do ponto de vista dos pais.

  1. (difícil) Um plug-in filho que apenas estende a funcionalidade ou altera a exibição (e semelhante) de um plug-in existente e, portanto, não pode existir sem o pai. Exemplo: BuddyPress »BuddyPress-FunkyCommentDisplay
  2. (normal) Um plug-in que possui funcionalidade estendida quando um plug-in filho é ativado. Exemplo: jQueryAttachmentCarousel »jQuerySlideDeck
  3. (flexível) Um plug-in que apenas adiciona um recurso. Exemplo: DisneyWonderlandTheme »MickeysSocialLinks

A seguir, tento esboçar o que acontece quando você atualiza o plug-in "other" e a verificação não funciona mais.

  • Anúncio 1) O plugin não poderia existir sem o BuddyPress ativado »O material está completamente quebrado.
  • Anúncio 2) O plug-in não pôde oferecer a opção de alternar entre o Carrossel e o SlideDeck ».
  • Anúncio 3) Os MickeysSocialLinks desaparecem.

Verifica

Existem três possibilidades de verificação, se você quiser saber se um plug-in está ativo:

  • A. A pasta existe?
  • B. O arquivo principal - opção 'active_plugins'- existe?
  • C. Existe uma função específica?

Se agora eu pegar meu plug-in Verificador de Link Interno como exemplo, que não oferece API pública e não deve ser estendido, não vejo motivo (como autor) para não alterar a nomeação de função interna sob demanda ou apenas por vontade . Portanto, se alguém tentasse pegar carona nesse plug-in, as coisas simplesmente quebrariam (dependendo da funcionalidade e da rigidez do pacote) na atualização. O mesmo vale para nomes de arquivos. Eu não teria nenhum motivo real (além disso, o plug-in seria desativado na atualização) para não alterar o nome do arquivo. A única coisa que me impediria de alterar o nome da pasta é que a verificação e notificação da atualização sejam executadas no nome do arquivo - se ele estiver hospedado no repositório oficial.

Então, eu diria que da parte mais fraca (fácil de mudar) para a mais difícil (muito falamos contra a mudança) de um plug-in (principal) seria:

função »nome do arquivo principal» pasta


Quando eu disse que uma verificação de função é menos frágil do que usar is_plugin_active(), presumi que a função em questão é aquela que o autor do plug-in incentiva explicitamente. O exemplo final disso seria a wp_pagenavi()tag de modelo oferecida pelo plugin WP-PageNavi.

A dificuldade em definir dependências é que não existe uma maneira padrão de identificar exclusivamente plugins que não envolvam nomes de arquivos.

Mais pensamentos sobre o assunto:

http://wordpress.org/support/topic/plugin-plugin-dependencies-unreliable-plugin-namingidentifying-scheme


Acho que até agora podemos resumir em três pontos:

  • Nós conversamos sobre tópicos ligeiramente diferentes
  • Concordamos que não há uma maneira à prova de balas para contornar o que eu pensei que o tópico seria
  • Pela sua compreensão da pergunta, você ofereceu um caminho válido a seguir

A maneira (até agora) mais inteligente que consigo pensar, que eu já vi em alguns (muito menos) plugins:

// inside the plugin file:
add_action( 'plugin_custom_hook', 'plugin_trigger' );
// inside some template:
do_action( 'plugin_custom_hook' );

Sem pensar muito em detalhes, mas acho que você pode conectar seu aviso a um filtro 'all' e verificar o filtro atual se ele foi acionado quando você está no shutdowngancho ...?


Usar ganchos funcionaria bem para dependências 'normais' e 'fracas'. A única desvantagem é que você ainda precisará usar function_exists()ou is_plugin_active()se deseja parar se a dependência não for atendida. Usar o filtro 'all' para isso seria IMO muito caro.

@scibu Este tópico foi direcionado ao tópico "seu". (Eu já deixei de falar sobre o meu). :)

Então, basicamente, se você precisar de uma dependência - e você tiver um bom autor -, ele poderá oferecer um gancho em vez disso / como substituto para uma tag de modelo. Porque o plug-in apenas se conectaria a ele se o gancho estivesse presente ou simplesmente não faria nada. E por outro lado, você não teria um erro quando os plugins não estivessem presentes.

Aqui está a parte difícil (ou mais das perguntas mais frequentes): Para escrever um aviso de administrador para informar o usuário sobre a dependência "Você precisa instalar» DisneyWonderLinks «", verifique o array_keys( $GLOBALS['wp_filter']['template_tag_like_hook'] ). Não tenho certeza se isso funcionaria, mas depois que a matriz deve estar acessível em ambos os lados (público / administrador).


Isso não funcionaria. Só porque um retorno de chamada está registrado em um gancho não significa que o gancho será acionado quando esperado. A única coisa que seria tipo de trabalho é usar o gancho 'shutdown', que você mencionou antes:

add_action( 'shutdown', function() {
  if ( !did_action( 'template_tag_like_hook' ) )
    echo 'Problem.';
} );

Obviamente, isso seria impresso na parte inferior, após a </html>tag, no front-end (já que é onde as tags de modelo são normalmente usadas), o que não é de muita utilidade.

Você pode tentar armazenar a mensagem em wp_options e exibi-la na área de administração, mas isso abriria uma nova lata de worms: invalidação, plugins de cache etc.

kaiser
fonte
Para constar, essa é uma maneira pouco ortodoxa de usar a funcionalidade do site. Isso me lembra c2.com/cgi/wiki
scribu
Sim, ele é. Mas não fazia ideia de como poderíamos continuar a discussão sem ocultá-la dos leitores posteriores.
kaiser
Eu não perceberia que postar a pergunta geraria uma discussão bastante :) Mas é realmente interessante e agradeço a vocês pelo esforço e tempo dando conselhos e fornecendo um debate ponderado. Eu acho que o conselho de scribu (um dos muitos) para usar a classe de ativação do TGM poderia oferecer uma solução para minha resposta, pelo menos de um ponto de vista meramente prático, vou analisá-lo. No entanto, ainda estou de olho em toda a discussão, porque também outros métodos propostos fazem sentido em certos cenários e é muito interessante para mim ler, obrigado!
Unfulvio