Как найти слаг (slug) плагина WordPress?
Я хочу узнать, как найти слаг плагина (слаг = внутреннее имя, используемое WordPress для обновления плагинов и определения, какие плагины активны в данный момент)? Обычно это имя папки плагина, но если у плагина нет папки, то это имя его файла (например, hello.php). Есть ли другие исключения?
- Имеет ли значение регистр символов (заглавные и строчные буквы)?
- Может ли плагин иметь слаг, отличный от имени его папки? Что произойдет, если есть плагин с именем hello.php и другой /hello.php/hello.php?

Разница между основным файлом плагина и его "слагом" — это область, где WordPress Codex мог бы быть более понятным. Я понимаю ваше замешательство, поскольку сам недавно сталкивался с этим (и испытывал разочарование).
Вот что я выяснил, проведя "детективную работу" с исходным кодом WordPress.
Основной файл плагина
Это уникальный способ, с помощью которого WordPress идентифицирует и записывает плагин. Он состоит из директории плагина И его основного файла (того, который содержит заголовок с различными метаданными, такими как версия, автор и т. д.).
Это выглядит примерно так: ваша-директория-плагина/основной-файл.php
Если вы посмотрите на данные активных плагинов (возвращаемые функцией get_option( 'active_plugins' )
), вы увидите, что WordPress использует именно этот файл для идентификации плагинов.
Можно представить его как относительный путь к основному файлу плагина (относительно директории wp-content/plugins/
). Абсолютный путь к основному файлу можно сформировать так: trailingslashit( WP_PLUGIN_DIR ) . $plugin_main_file
Ядро WordPress генерирует путь к основному файлу плагина следующим образом:
$plugin_main_file = plugin_basename( trim( $plugin_main_file_absolute_path ) );
Слаг плагина
Можно было бы ожидать, что "слаг" плагина — это своего рода стандартизированный идентификатор, подобно тому, как слаг поста работает для записей, чтобы его можно было передавать в функции WordPress.
Но это не так. После поиска в ядре WordPress упоминаний о слагах плагинов (или тем) и почти ничего не найдя, я понял следующее.
Единственные настоящие слаги — это те, которые используются в URL-адресах: записи, страницы, таксономии и т. д. Вся суть создания URL-дружественной версии названия (например, заголовка записи) заключается в том, чтобы использовать её в URL.
Но где мы используем "слаги" тем/плагинов в URL?
На отдельных установках WordPress — ни в админке, ни на фронтенде.
Однако есть место, тесно связанное с кодом WordPress — сайт WordPress.org. Людям трудно различать эти две вещи, и среди разработчиков стало распространенным мнение, что слаги тем или плагинов с WordPress.org должны работать так же, как слаги записей или страниц.
Они служат той же цели, но на разных сайтах. На WordPress.org они используются для уникальной идентификации темы или плагина (например, в URL: https://wordpress.org/plugins/akismet/
).
Но когда дело доходит до отдельных установок WordPress, такая же уникальность не может быть гарантирована, потому что нет централизованного контроля (как на WordPress.org). Это могло бы сработать, если бы все плагины и темы были с WordPress.org, но, к счастью, это не так.
Как WordPress использует слаги тем/плагинов?
Ядро WordPress не полагается на слаги тем/плагинов для таких операций, как установка, активация, обновление или удаление.
Для тем оно использует директорию темы, потому что точка входа — это файл style.css
(нельзя использовать другой CSS-файл для заголовка темы).
Для плагинов оно полагается на директорию плагина И основной файл, поскольку плагины могут называть свой основной файл как угодно.
Единственный случай, когда ядро использует слаги тем/плагинов — при работе с темами и плагинами из каталога WordPress.org: получение списков, проверка обновлений, отправка статистики использования и т. д.
Подводя итог о слагах плагинов: если вы видите данные плагина с полем slug
, в 99% случаев это будет слаг плагина на WordPress.org.
Как идентифицировать плагины?
Если вам нужно программно активировать, обновить, деактивировать или удалить плагин, используйте основной файл плагина. Его можно получить так (в основном файле вашего плагина):
$plugin_file = plugin_basename( __FILE__ );
Если вы хотите обратиться к определённому плагину из другого плагина, всё немного сложнее, так как придётся полагаться на "угадывание".
Можно жестко прописать название плагина, найти его в списке всех плагинов (см. get_plugins()) и получить его основной файл.
Если вы знаете класс или функцию, определённую этим плагином, можно использовать reflection (см. этот ответ для классов и этот для функций).
Надеюсь, это поможет вам и другим, кто сталкивается с трудностями в понимании "слагов плагинов". Это сэкономило бы мне пару часов :)

Строка, используемая в WordPress для идентификации плагина, это:
plugin_basename($file);
… где $file
— это файл с заголовками плагина.
Поэтому, если вы находитесь в своем плагине, получите слаг с помощью:
$slug = plugin_basename( __FILE__ );

plugin_basename($file); Не является slug с версии 3.8.1. Это путь в формате папка/главный_файл_плагина.php. Например, "slug" плагина Akismet — это не "akismet/akismet.php", а просто "akismet".

Если вы установите WP-CLI, то сможете получить список плагинов с их slug и версией прямо из командной строки:
> wp plugin list
Я понимаю, что это, вероятно, не совсем то, что вам нужно, если требуется найти slug в коде, но этот способ помог мне при работе с плагином TGM-Plugin-Activation.
Мне сложно представить работу с WordPress без WP-CLI, в целом это очень полезный инструмент для выполнения многих стандартных задач, связанных с WordPress.

К сожалению, slug (идентификатор) плагина возвращается через Update API, и ответ на этот вопрос не так очевиден, если не запрашивать сам API. Однако, если вы хотите увидеть список текущих slug'ов ваших плагинов и связанных с ними данных, вы можете просто выполнить:
print_r(get_site_transient('update_plugins'));
Но эта информация не будет доступна для только что установленного плагина в течение 12 часов. Для таких случаев потребуется другой подход, например, использовать модифицированную версию кода из wp_update_plugins
в файле wp-includes/update.php
...
После тестирования выяснилось, что независимо от имени файла плагина, его расположения или регистра букв, именно поле Plugin Name
генерирует slug для обновлений, скорее всего, через функцию sanitize_title
. Таким образом, правильный ответ должен быть таким:
// если у вас есть базовое имя плагина:
// $pluginfile = WP_PLUGIN_DIR.'/'.$pluginbasename;
// или, если у вас уже есть абсолютный путь:
$plugin = get_plugin_data($pluginfile);
$pluginslug = sanitize_title($plugin['Name']);

+1 и дополнительное замечание: это может измениться со временем, так как команда wordpress.org явно указала, что методология расчета слагов пока не полностью окончательна

Не уверен, что это точно, я пытался сделать это для плагина, но это не сработало: имя плагина возвращается как "Responsive WordPress Slider - Soliloquy Lite", а слаг: soliloquy-lite

Подозреваю, это потому что слаг генерируется в момент отправки плагина в репозиторий и не меняется с именем позже... в большинстве случаев он совпадает с именем директории, но если есть исключения для обоих, это может быть как один, так и другой вариант. Не идеально :-/

Для ясности, добавлю к оригинальному сообщению.
Я нахожу слаг плагина следующим образом: сначала перехожу в папку с плагинами, затем открываю папку нужного плагина и нахожу файл, содержащий приведённый ниже код. Как только вы нашли этот файл, имя файла без расширения и будет вашим слагом плагина.
Например, если я нашёл приведённый ниже код в файле с именем advanced-plugin-awesomeness.php, то мой слаг будет advanced-plugin-awesomeness.
Надеюсь, это поможет!
/*
Plugin Name: Название плагина здесь
Version: 2.4.6
Description: Описание плагина здесь
Author: Автор плагина здесь

-1, так как хотя большинство имен файлов и каталогов совпадают, это не надежный метод, поскольку слаг обновления на самом деле является именем каталога, а не файла (если только каталога нет).

Попробуйте это:
function get_slugname(){
$tmp = array();
$plugins_all = get_plugins() ;
$plugin_slug = explode('/',dirname(plugin_basename(__FILE__)));
foreach ($plugins_all as $key=>$value) {
if ($plugin_slug[0] == explode('/',$key)[0] ) {
$tmp = $value;
$tmp['slug'] = explode('/',$key)[0];
$tmp['file'] = explode('/',$key)[1];
}
}
return $tmp;
}

Пожалуйста, отредактируйте ваш ответ и добавьте объяснение того, что делает этот код.
