213 lines
8.3 KiB
PHP
213 lines
8.3 KiB
PHP
<?php
|
||
/**
|
||
* WP Multi – Modul: Custom Login-URL
|
||
*
|
||
* Automatisch aus wp-multi.php ausgelagert. Wird über den Loader in
|
||
* wp-multi.php eingebunden (nur wenn das WP Multi Toolkit aktiv ist).
|
||
*/
|
||
|
||
if (!defined('ABSPATH')) { exit; }
|
||
|
||
/*
|
||
* Custom Login-URL — Admin-Panel-Adresse ändern (versteckt wp-admin / wp-login.php)
|
||
*
|
||
* Ersetzt die Standard-Login-Adresse durch einen eigenen Slug, z. B. /team/.
|
||
* Standardmäßig DEAKTIVIERT (leerer Slug), damit ohne bewusste Aktivierung
|
||
* nichts an der Erreichbarkeit des Backends geändert wird.
|
||
*/
|
||
|
||
// Liefert den konfigurierten Login-Slug (leer = Feature aus)
|
||
function wp_multi_login_slug() {
|
||
$slug = get_option('wp_multi_login_slug', '');
|
||
return is_string($slug) ? trim($slug, '/') : '';
|
||
}
|
||
|
||
// Feature ist nur aktiv, wenn ein Slug gesetzt ist UND Permalinks aktiv sind
|
||
function wp_multi_login_active() {
|
||
return wp_multi_login_slug() !== '' && get_option('permalink_structure') && !is_multisite();
|
||
}
|
||
|
||
// Vollständige neue Login-URL
|
||
function wp_multi_login_new_url($scheme = null) {
|
||
return user_trailingslashit(home_url('/', $scheme) . wp_multi_login_slug());
|
||
}
|
||
|
||
// Pfad-Anteil (ohne Domain) der Home-URL, z. B. "" oder "/blog"
|
||
function wp_multi_login_home_path() {
|
||
return untrailingslashit((string) parse_url(home_url(), PHP_URL_PATH));
|
||
}
|
||
|
||
// Sendet eine echte 404-Antwort und beendet die Ausführung (verstecktes Login)
|
||
function wp_multi_login_die_404() {
|
||
status_header(404);
|
||
nocache_headers();
|
||
if (function_exists('wp_die')) {
|
||
// Nutze die Theme-404 wenn möglich, sonst schlichte Meldung
|
||
wp_die(__('Seite nicht gefunden.', 'wp-multi'), '404', array('response' => 404));
|
||
}
|
||
exit;
|
||
}
|
||
|
||
// Ersetzt "wp-login.php" in generierten URLs durch den eigenen Slug
|
||
function wp_multi_login_filter_url($url, $scheme = null) {
|
||
if (strpos($url, 'wp-login.php') === false) {
|
||
return $url;
|
||
}
|
||
if (is_ssl()) {
|
||
$scheme = 'https';
|
||
}
|
||
$query = parse_url($url, PHP_URL_QUERY);
|
||
$args = array();
|
||
if ($query) {
|
||
parse_str($query, $args);
|
||
}
|
||
$new = wp_multi_login_new_url($scheme);
|
||
if (!empty($args)) {
|
||
// add_query_arg kodiert selbst; parse_str liefert bereits dekodierte Werte.
|
||
$new = add_query_arg($args, $new);
|
||
}
|
||
return $new;
|
||
}
|
||
|
||
function wp_multi_login_filter_site_url($url, $path, $scheme, $blog_id = null) {
|
||
return wp_multi_login_filter_url($url, $scheme);
|
||
}
|
||
|
||
function wp_multi_login_filter_wp_redirect($location) {
|
||
return wp_multi_login_filter_url($location);
|
||
}
|
||
|
||
// Registriert die Filter und den Request-Handler, sobald WordPress geladen ist
|
||
function wp_multi_login_init() {
|
||
if (!wp_multi_login_active()) {
|
||
return;
|
||
}
|
||
|
||
add_filter('site_url', 'wp_multi_login_filter_site_url', 10, 4);
|
||
add_filter('network_site_url', 'wp_multi_login_filter_site_url', 10, 4);
|
||
add_filter('wp_redirect', 'wp_multi_login_filter_wp_redirect', 10, 1);
|
||
add_filter('login_url', 'wp_multi_login_filter_wp_redirect', 10, 1);
|
||
add_filter('logout_url', 'wp_multi_login_filter_wp_redirect', 10, 1);
|
||
add_filter('lostpassword_url', 'wp_multi_login_filter_wp_redirect', 10, 1);
|
||
add_filter('register_url', 'wp_multi_login_filter_wp_redirect', 10, 1);
|
||
}
|
||
add_action('plugins_loaded', 'wp_multi_login_init', 1);
|
||
|
||
// Fängt die eingehende Anfrage ab: geheimer Slug lädt das Login, wp-login.php/wp-admin werden versteckt
|
||
function wp_multi_login_handle_request() {
|
||
if (!wp_multi_login_active()) {
|
||
return;
|
||
}
|
||
|
||
// Systemendpunkte niemals blockieren
|
||
if ((defined('DOING_AJAX') && DOING_AJAX) || (defined('DOING_CRON') && DOING_CRON) || (defined('REST_REQUEST') && REST_REQUEST)) {
|
||
return;
|
||
}
|
||
|
||
$uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
|
||
$path = untrailingslashit((string) parse_url($uri, PHP_URL_PATH));
|
||
$home_path = wp_multi_login_home_path();
|
||
$login_path = $home_path . '/' . wp_multi_login_slug();
|
||
|
||
// 1) Aufruf des geheimen Slugs → echtes wp-login.php ausliefern
|
||
if ($path === $login_path) {
|
||
$GLOBALS['pagenow'] = 'wp-login.php';
|
||
require_once ABSPATH . 'wp-login.php';
|
||
exit;
|
||
}
|
||
|
||
// 2) Direkter Aufruf von wp-login.php (nicht über den Slug) → verstecken
|
||
if (strpos($uri, 'wp-login.php') !== false) {
|
||
wp_multi_login_die_404();
|
||
}
|
||
|
||
// 3) Der gesamte /wp-admin-Bereich für nicht eingeloggte Besucher → verstecken,
|
||
// statt zum versteckten Login weiterzuleiten. admin-ajax.php und admin-post.php
|
||
// bleiben ausdrücklich erreichbar (auch für Gäste / nopriv-Aktionen).
|
||
if (!is_user_logged_in()) {
|
||
$admin_path = $home_path . '/wp-admin';
|
||
$in_admin = ($path === $admin_path || strpos($path, $admin_path . '/') === 0);
|
||
$is_endpoint = (strpos($uri, 'admin-ajax.php') !== false || strpos($uri, 'admin-post.php') !== false);
|
||
if ($in_admin && !$is_endpoint) {
|
||
wp_multi_login_die_404();
|
||
}
|
||
}
|
||
}
|
||
add_action('wp_loaded', 'wp_multi_login_handle_request');
|
||
|
||
// Einstellung registrieren (mit Sanitisierung gegen reservierte Slugs)
|
||
function wp_multi_login_register_setting() {
|
||
register_setting('wp_multi_login_url_group', 'wp_multi_login_slug', array(
|
||
'type' => 'string',
|
||
'sanitize_callback' => 'wp_multi_login_sanitize_slug',
|
||
'default' => '',
|
||
));
|
||
}
|
||
add_action('admin_init', 'wp_multi_login_register_setting');
|
||
|
||
function wp_multi_login_sanitize_slug($value) {
|
||
$value = sanitize_title(trim((string) $value, '/'));
|
||
$reserved = array('wp-admin', 'wp-login', 'wp-content', 'wp-includes', 'admin-ajax', 'admin-post', 'wp-json', 'index');
|
||
if (in_array($value, $reserved, true)) {
|
||
add_settings_error('wp_multi_login_slug', 'reserved', __('Dieser Slug ist reserviert und kann nicht verwendet werden.', 'wp-multi'));
|
||
return '';
|
||
}
|
||
return $value;
|
||
}
|
||
|
||
// Admin-Seite "Login-URL"
|
||
function wp_multi_login_url_page() {
|
||
if (!current_user_can('manage_options')) {
|
||
wp_die(__('Zugriff verweigert.', 'wp-multi'));
|
||
}
|
||
|
||
$slug = wp_multi_login_slug();
|
||
$pretty = (bool) get_option('permalink_structure');
|
||
|
||
wpmt_admin_page_open(
|
||
__('Login-URL', 'wp-multi'),
|
||
__('Eigene Adresse für das Login / Admin-Panel festlegen', 'wp-multi')
|
||
);
|
||
|
||
if (is_multisite()) {
|
||
wpmt_admin_notice('error', __('Dieses Feature ist in einem Multisite-Netzwerk nicht verfügbar.', 'wp-multi'));
|
||
wpmt_admin_page_close();
|
||
return;
|
||
}
|
||
|
||
if (!$pretty) {
|
||
wpmt_admin_notice('warning', __('Für dieses Feature müssen „hübsche Permalinks" aktiviert sein (Einstellungen → Permalinks, nicht „Einfach"). Solange das nicht der Fall ist, bleibt die Login-URL unverändert.', 'wp-multi'));
|
||
}
|
||
|
||
wpmt_admin_notice('warning', __('Achtung: Merke dir die neue Adresse gut! Wenn du sie vergisst, kommst du nicht mehr ins Backend und musst das Feld per Datenbank oder FTP zurücksetzen. Leeres Feld = Standard-Login (/wp-login.php) bleibt aktiv.', 'wp-multi'));
|
||
|
||
if ($slug && $pretty) {
|
||
wpmt_admin_notice('success', sprintf(
|
||
__('Aktive Login-Adresse: %s', 'wp-multi'),
|
||
'<a href="' . esc_url(wp_multi_login_new_url()) . '"><strong>' . esc_html(wp_multi_login_new_url()) . '</strong></a>'
|
||
));
|
||
}
|
||
|
||
wpmt_admin_card_open(__('Einstellung', 'wp-multi'));
|
||
?>
|
||
<form method="post" action="options.php">
|
||
<?php settings_fields('wp_multi_login_url_group'); ?>
|
||
<div class="wpm-field">
|
||
<label class="wpm-field__label" for="wp_multi_login_slug"><?php esc_html_e('Login-Slug', 'wp-multi'); ?>
|
||
<small class="wpm-field__hint"><?php esc_html_e('Nur Kleinbuchstaben, Zahlen und Bindestriche. Leer lassen = deaktiviert.', 'wp-multi'); ?></small>
|
||
</label>
|
||
<div>
|
||
<span style="color:var(--wpm-text-muted);"><?php echo esc_html(trailingslashit(home_url('/'))); ?></span>
|
||
<input type="text" id="wp_multi_login_slug" name="wp_multi_login_slug" value="<?php echo esc_attr($slug); ?>" placeholder="team" style="max-width:220px; display:inline-block;">
|
||
</div>
|
||
</div>
|
||
<?php submit_button(__('Speichern', 'wp-multi')); ?>
|
||
</form>
|
||
<?php
|
||
wpmt_admin_card_close();
|
||
|
||
wpmt_admin_page_close();
|
||
}
|
||
|
||
|