Plugins em diretórios com links simbólicos?

20

Quando desenvolvo plugins, eu os testo em várias versões do WordPress, associando o diretório do meu plugin nos diferentes wp-contentdiretórios. Isso é ótimo, pois só preciso editar os arquivos uma vez, mas quebra uma construção importante para gerar referências aos recursos no meu plug-in: __FILE__refere-se ao local do plug-in físico, não ao local wp-content. Como devo resolver isso?

Minha estrutura de diretórios é assim:

  • /path/to/wordpress/development/dir/
    • plugin-development/
      • monkeyman-rewrite-analyzer/
        • monkeyman-rewrite-analyzer.php
        • js/
          • monkeyman-rewrite-analyzer.js
    • versions/
      • 3.1/
        • wp-content/
          • plugins/
            • monkeyman-rewrite-analyzer como um link simbólico para o plug-in acima
      • 3.1-multi-dir/
        • wp-content/
          • plugins/
            • monkeyman-rewrite-analyzer como um link simbólico para o plug-in acima
      • 3.1-multi-domain/
        • wp-content/
          • plugins/
            • monkeyman-rewrite-analyzer como um link simbólico para o plug-in acima

Se eu quiser enfileirar o arquivo Javascript, eu deveria usar plugins_url( 'monkeyman-rewrite-analyzer.js', [base file] ), mas usando __FILE__aqui não vai funcionar, porque o caminho do arquivo real será /path/to/wordpress/development/dir/plugin-development/monkeyman-rewrite-analyzer/monkeyman-rewrite-analyzer.php, não /path/to/wordpress/development/dir/versions/*/wp-content/plugins/monkeyman-rewrite-analyzer/monkeyman-rewrite-analyzer.php, de modo WordPress não pode tirar a primeira parte para fora e gerar uma URL relativa à instalação do WordPress.

Jan Fabry
fonte

Respostas:

6

O problema pode ser parcialmente resolvido com um plug-in obrigatório de usar no plugins_urlfiltro.

Ele não trata de todos os outros casos em que plugin_basename()é usado, como register_activation_hook()e co.

Mais informações: http://core.trac.wordpress.org/ticket/16953

scribu
fonte
Eu acredito que o uso WP_PLUGIN_URLnão é recomendado porque os administradores devem ter permissão para alterar o nome do diretório deste plug-in específico, mas há outro motivo para evitá-lo? E, de fato, seu ingresso seria uma solução simples.
Jan Fabry
Pelo contrário. WP_PLUGIN_URL contém apenas o URL que aponta diretamente para o diretório 'plugins'. Veja a resposta atualizada.
Scrib:
@ scribu: Mas e se meus plugins residirem, /external/folder/banana-plugin/mas o administrador vincular esse diretório como /httpd-root/wp-content/plugins/apple-plugin/? Então ele tentará ir /wp-content/plugins/banana-plugin/, não? E acredito que o administrador deve ser livre para escolher os nomes de diretório de plugins individuais?
Jan Fabry
Não vou mais discutir com você sobre isso, porque encontrei a solução: o filtro 'plugins_url'. Resposta atualizada novamente.
scribu
FWIW, esta solução pode estar sujeita a erros e depende dos desenvolvedores de plug-ins usando apenas plugins_url () após o carregamento de todos os plug-ins; caso contrário, você não poderá registrar um filtro antes que a função seja chamada. o plugin Akismet e muitos outros têm esse problema.
jerclarke
3

Atualmente, uso um truque para obter o local do arquivo relativo ao WordPress: wp_get_active_and_valid_plugins()retorna os caminhos do arquivo, wp_settings.phppassa-os por cima e inclui os arquivos . Portanto, a $pluginvariável global se refere ao seu plug-in atual (é claro apenas quando o plug-in é carregado, então eu o salvo em uma variável global prefixada):

$monkeyman_Rewrite_Analyzer_file = $plugin;

Como os plug-ins também podem ser carregados como plug-ins obrigatórios ou de rede e esses loops usam outros nomes de variáveis , o código completo se parece com o seguinte:

$monkeyman_Rewrite_Analyzer_file = __FILE__;
if ( isset( $mu_plugin ) ) {
    $monkeyman_Rewrite_Analyzer_file = $mu_plugin;
}
if ( isset( $network_plugin ) ) {
    $monkeyman_Rewrite_Analyzer_file = $network_plugin;
}
if ( isset( $plugin ) ) {
    $monkeyman_Rewrite_Analyzer_file = $plugin;
}

O fallback ainda é __FILE__, portanto, se alguém alterar o nome da variável de loop no futuro, meu código ainda funcionará em 99% de todas as instalações, apenas minha instalação de desenvolvimento falhará e eu posso lançar uma nova versão com facilidade.

Jan Fabry
fonte
Ótima solução @Jan. Eu implementei algo semelhante chamando as funções e fazendo um loop porque esqueci que essas variáveis ​​estavam acessíveis como global. Graças ao seu post aqui, percebi que poderia torná-lo muito mais simples. BTW, eu também estou testando false === strpos( __FILE__, WP_CONTENT_DIR )antes de executar suas instruções if porque estou assumindo que o plug-in está no WP_CONTENT_DIRnão está vinculado; Espero que seja lógica válida.
21812 Mike12:
0

Um comentário no bug 46260 sugere usar em $_SERVER["SCRIPT_FILENAME"]vez de __FILE__. Isto funciona?

fuxia
fonte
11
Não, isso não muda nos arquivos incluídos. Então, se index.phpinclui library.php, $_SERVER['SCRIPT_FILENAME']em library.phpainda será index.php. Mas obrigado pela referência ao bug, eu o seguirei de perto!
Jan Fabry
0

$_SERVER["SCRIPT_FILENAME"]funciona se você usá-lo corretamente. Você só precisa usá-lo para definir um caminho base e, em seguida, incluir seus arquivos usando um caminho relativo a esse caminho base.

Algo como:

$plugin_dir = dirname($_SERVER["SCRIPT_FILENAME"]);
$myFile = $plugin_dir."/includes/js/myJavascriptFile.js";

Observe que isso é mais útil quando você ainda não tem acesso ao wp-blog-header.php (por exemplo, no processamento de uma solicitação de formulário baseada no Ajax)

Chad Furman
fonte