Как плагин может получить собственный номер версии?
Существует ли API, который я могу вызвать внутри своего плагина, чтобы определить версию плагина?
Мне нужно, чтобы мой плагин выводил HTML-комментарий с собственным номером версии... для диагностических целей.

@david: И @Adam Backtrom, и @Viper007Bond дали хорошие советы, поэтому я решил последовать их рекомендациям и попробовать реализовать что-то подобное. Результат представлен ниже.
Далее следует плагин под названием WP Active Plugins Data, который анализирует метаданные заголовков всех активных плагинов при активации любого плагина и сохраняет все метаданные каждого плагина в виде массива в опции wp_options
. Я разработал его как для обычных плагинов WordPress, так и для мультисайтовых плагинов, работающих на уровне сети. Вы можете скачать его здесь из gist, но я также привел код ниже для вашего ознакомления:
<?php
/*
Plugin Name: WP Active Plugins Data
Plugin URI: http://mikeschinkel.com/wordpress-plugins/wp-active-plugins-data/
Description: Загружает данные плагинов при их активации и сохраняет в wp_options для быстрого доступа.
Version: 0.1
Author: Mike Schinkel
Author URI: http://mikeschinkel.com
Note: Написано для http://wordpress.stackexchange.com/questions/361/is-there-a-way-for-a-plug-in-to-get-its-own-version-number
*/
require_once(ABSPATH.'wp-admin/includes/plugin.php');
function get_active_plugin_version($plugin_path_file, $sitewide = false) {
return get_active_plugin_attribute($plugin_path_file,'Version');
}
function get_active_plugin_attribute($plugin_path_file, $attribute) {
$all_plugins_data = get_active_plugins_data($plugin_path_file,$sitewide);
return (isset($all_plugins_data[$attribute]) ? $all_plugins_data[$attribute] : false);
}
function get_active_plugins_data($plugin_path_file, $sitewide = false) {
$failsafe = false;
$plugin = plugin_basename(trim($plugin_path_file));
$sitewide = (is_multisite() && ( $sitewide || is_network_only_plugin($plugin)));
if ($sitewide) {
$all_plugins_data = get_site_option('active_sitewide_plugin_data',array());
} else {
$all_plugins_data = get_option('active_plugin_data',array());
}
if (!$failsafe && !is_array($all_plugins_data) || count($all_plugins_data)==0) {
$failsafe = true; // Избегаем бесконечной рекурсии
if ($sitewide) {
$active_plugins = get_site_option('active_sitewide_plugins',array());
} else {
$active_plugins = get_option('active_plugins',array());
}
persist_active_plugin_data(null,$active_plugins,$sitewide);
$all_plugins_data = get_active_plugin_version($plugin_path_file,$sitewide);
}
return $all_plugins_data[$plugin_path_file];
}
add_action('update_site_option_active_sitewide_plugins','persist_sitewide_active_plugin_data',10,2);
function persist_sitewide_active_plugin_data($option, $plugins) {
persist_active_plugin_data(null,$plugins,'sitewide');
}
add_filter('update_option_active_plugins','persist_active_plugin_data',10,2);
function persist_active_plugin_data($old_plugins, $new_plugins, $sitewide=false) {
$active_plugin_data = array_flip($new_plugins);
$plugin_dir = WP_PLUGIN_DIR;
foreach($new_plugins as $plugin) {
$active_plugin_data[$plugin] = get_plugin_data("$plugin_dir/$plugin");
}
if ($sitewide)
update_site_option('active_sitewide_plugin_data',$active_plugin_data);
else
update_site_option('active_plugin_data',$active_plugin_data);
}
Хотите посмотреть, как это работает? Вот тестовый файл, который можно разместить в корне вашего сайта WordPress (http://example.com/test.php
). Убедитесь, что у вас активированы и этот плагин, и Akismet, прежде чем запускать тест.
<?php
/*
* test.php - Разместите в корне сайта WordPress.
*
* Перед запуском убедитесь, что активированы как Akismet, так и плагин WP Active Plugin Data.
*
*/
include "wp-load.php";
header('Content-type:text/plain');
$akismet = "akismet/akismet.php";
echo "Версия Akismet: " . get_active_plugin_version($akismet);
echo "\n\nОписание Akismet: " . get_active_plugin_attribute($akismet,'Description');
echo "\n\nВсе данные Akismet:\n";
print_r(get_active_plugins_data($akismet));
Если это не совсем то, что вам нужно, по крайней мере, это может послужить хорошей отправной точкой. Надеюсь, это поможет.

+1. Отличная работа, Майк. Интересно, сколько плагинов появится благодаря этому StackExchange. :)

В админке доступна функция: get_plugin_data()
. В шаблонах, я думаю, вам понадобится, чтобы плагин хранил эти данные в PHP, например, установил константу или глобальную переменную, и сохранял это значение синхронизированным с номером версии в заголовке плагина.
Файл wp-settings.php
вызывает функцию wp_get_active_and_valid_plugins()
, которая получает данные из опции сайта active_plugins
. Эта опция содержит только путь к файлу плагина, и wp-settings.php
просто выполняет include_once
для этого файла, поэтому метаданные плагина никогда не извлекаются.

Вы можете разбирать метаданные вашего плагина (эта информация в начале файла), но для повышения производительности лучше просто задать собственную PHP-переменную с соответствующим номером версии. Когда вы обновляете плагин, просто обновите оба номера версии.
В краткосрочной перспективе это потребует немного больше работы, но в долгосрочной перспективе это намного лучше.

Для производительности может быть лучше просто определить переменную, но также не очень удобно менять номер версии в двух местах. Для тем есть похожая функция wp_get_theme, которая даже используется в примерах: https://codex.wordpress.org/Child_Themes Это похоже на плохой дизайн в WordPress, было бы лучше, если бы мы могли установить версию плагина через переменную и затем повторно использовать эту переменную в функциях wp_enqueue_style и wp_enqueue_script.
