Мой коллега перенес сайт клиента, готовясь принять на себя управление его учетной записью, и был удивлен, когда после успешной миграции сайт не работал должным образом. Эта проблема вызвала немалое разочарование в отрасли. Агентство создало кастомные функции, недоступные клиенту — через SFTP или администрирование WordPress. Позже я объясню, как… и как мне удалось обойти эту проблему.
В WordPress мю-плагины (обязательные плагины) — это специальные типы плагинов WordPress, которые активируются автоматически и не могут быть деактивированы из панели администратора WordPress. внутри внутри мю-плагины обозначает должен быть использован.
Когда ты идешь в Плагины В панели администратора WordPress вы увидите только обычные плагины, которые можно активировать, деактивировать и управлять ими индивидуально. С другой стороны, mu-плагины автоматически активируются и не появляется в этом списке. Вот некоторые ключевые моменты о mu-плагинах:
- Расположение: Mu-плагины расположены в отдельном каталоге с именем
mu-plugins
внутриwp-content
в каталоге установки WordPress. - Автоматическая активация: В отличие от обычных плагинов, mu-плагины активируются автоматически и не могут быть деактивированы из панели администратора WordPress. Они всегда активны, пока находятся в этом
mu-plugins
каталог. - Приоритет: Mu-плагины загружаются раньше обычных плагинов. Это означает, что у них есть возможность переопределить или изменить поведение обычных плагинов.
- Соглашение об именовании: Mu-плагины не следуют тому же соглашению об именах, что и обычные плагины. Они могут иметь любое имя, но должны иметь расширение файла.
.php
. Например,my-custom-functions.php
может быть допустимым именем файла плагина mu. - Случаи использования: Mu-плагины обычно используются:
- Реализация специфичного для сайта функционала, который должен быть всегда активен.
- Изменение базового поведения WordPress или переопределение функций по умолчанию.
- Заставьте определенные плагины работать на всех сайтах в сети с несколькими сайтами.
- Использование пользовательского кода или модификаций, которые не должны быть доступны или отключены администраторами сайта.
- Несколько сайтов: В многосайтовой сети WordPress mu-плагины являются глобальными и влияют на все сайты в сети. Они загружаются раньше обычных плагинов на каждом сайте.
- Обновления: Mu-плагины нет можно обновить через административную панель WordPress. Их необходимо обновить вручную, заменив соответствующие файлы.
mu-plugins
каталог.
В данном конкретном случае у агентства был плагин mu, содержащий родительский каталог, в котором были созданы специальные плагины для клиента. Этот родительский каталог находился в их среде хостинга, но вообще не был доступен клиенту. На мой взгляд, это действительно угрожает. При продвижении WordPress среди ваших клиентов ожидается платформа с открытым исходным кодом.
Скрывая код от своих клиентов, вы лишаете их возможности мигрировать от вас или управлять экземпляром самостоятельно. По сути, вы держите их в заложниках, если они не создадут новый сайт с нуля. Я не говорю, что агентство сделало что-то противозаконное… Я уверен, что у них была информация об этом в их MSA или SOW. Однако это не делает это правильным.
Плагин WordPress: как идентифицировать и загрузить mu-плагины
Если вы можете выполнить код PHP, вы в конечном итоге сможете получить доступ к этому коду. Итак, я написал собственный плагин, который можно было установить на сервер, и создал шорткод, в котором перечислены плагины mu в каталоге. Я создал черновую страницу с [listmuplugins]
содержимое и просмотрели его в новом окне. Это предоставило мне плагин mu, установленный агентством.
Примечание: mu-plugin
каталог виден через SFTP, но они сделали что-то очень хитрое. Когда я открыл их плагин, я обнаружил, что они написали функцию для включения каталога, который был недоступен в среде хостинга клиента! Поэтому я обновил свой код, чтобы иметь возможность искать конкретный каталог, в который они были включены. [listmuplugins dir="/custom/path/"]
.
Когда я обновил шорткод до пути, который они указали в своем mu-plugin
, я мог прочитать и загрузить каждый плагин, необходимый для работы сайта. Вот скриншот вывода (я удалил все заказы агентства mu-plugins
).
После этого я смог написать собственные плагины, которые исправляли все проблемы сайта. Поскольку я не знал, есть ли у них юридический контракт, я не хотел просто копировать код агентства… несмотря на то, что у них не было никакой информации об авторских правах в источнике.
Как использовать этот плагин
Я не буду публиковать его в репозитории WordPress, поскольку считаю, что его нельзя распространять без ответственности. Вот как вы можете использовать его, если вам это нужно.
- Поддерживать: Сохраните весь код как
listmuplugins.php
в новой папке с именемlistmuplugins
внутри вашего WordPress/wp-content/plugins/
каталог. Или вы можете сжать каталог и файл PHP и загрузить их с помощью панели администратора плагина WordPress. - Активировать: Активируйте названный плагин Список плагинов MU с загрузкой и структурой каталогов в панели управления плагином WordPress.
- Использование короткого кода:
[listmuplugins]
: список плагинов MU, установленных на вашем сайте по умолчанию.wp-content/mu-plugins/
каталог.[listmuplugins dir="/custom/path/"]
: выводит список плагинов MU из указанного каталога.
<?php
/*
Plugin Name: List MU Plugins with Download and Directory Structure
Description: Lists Must-Use Plugins with the ability to download their source code, and displays the directory structure. Directory can be specified in the shortcode.
Version: 2.0
Author: Douglas Karr
Author URI:
*/
function list_mu_plugins_shortcode( $atts ) {
$atts = shortcode_atts( array(
'dir' => WPMU_PLUGIN_DIR // Default to site's MU Plugins directory
), $atts );
$dir = $atts['dir'];
// Validate the directory path
if ( ! is_dir( $dir ) || ! is_readable( $dir ) ) {
return "<p>MU Plugins directory not found or not readable.</p>\n";
}
$output = "<h2>List of Included MU Plugins:</h2>\n";
$output .= list_directory_contents( $dir );
return $output;
}
add_shortcode( 'listmuplugins', 'list_mu_plugins_shortcode' );
function list_directory_contents( $dir ) {
$output = "<ul>\n";
$items = scandir( $dir );
foreach ( $items as $item ) {
if ( $item === '.' || $item === '..' ) {
continue;
}
$path = $dir . '/' . $item;
if ( is_dir( $path ) ) {
$output .= '<li><strong>' . esc_html( $item ) . '/</strong>';
$output .= list_directory_contents( $path );
$output .= '</li>';
} else {
$output .= '<li>' . esc_html( $item );
if ( current_user_can( 'manage_options' ) ) {
$download_link = add_query_arg( ['mu_plugin_download' => $item] );
$output .= ' <a href="' . esc_url( $download_link ) . '">Download</a>';
}
$output .= '</li>';
}
}
$output .= "</ul>\n";
return $output;
}
// Handle the download request
function handle_mu_plugin_download() {
if ( isset( $_GET['mu_plugin_download'] ) && current_user_can( 'manage_options' ) ) {
$filename = sanitize_file_name( $_GET['mu_plugin_download'] );
$filepath = WPMU_PLUGIN_DIR . '/' . $filename;
if ( file_exists( $filepath ) && is_readable( $filepath ) ) {
header( 'Content-Description: File Transfer' );
header( 'Content-Type: application/octet-stream' );
header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate' );
header( 'Pragma: public' );
header( 'Content-Length: ' . filesize( $filepath ) );
readfile( $filepath );
exit;
} else {
wp_die( 'File not found or not readable.' );
}
}
}
add_action( 'init', 'handle_mu_plugin_download' );