Руководство по созданию страницы регистрации в мультисайте

Руководство по созданию страницы регистрации в мультисайте

Создаем собственную страницу регистрации для мультисайта взамен стандартной wp-signup.php.

Обновленная версия статьи на WP Magazine

Мультисайт позволяет использовать одну установку WordPress для нескольких сайтов одновременно. При этом каждый сайт имеет свои собственные таблицы в базе данных с уникальным префиксом, содержащим ID сайта, но таблицы с данными зарегистрированных людей общие для всех. Это несомненный плюс и зарегистрировавшись однажды можно получить аккаунт сразу на нескольких сайтах с разными полномочиями. Для автоматического назначения ролей новым пользователям используется Multisite User Management. Подробности о создании и примерах использования мультисайта читайте в материале «Что такое WordPress Multisite».

В обычной установке WordPress страницу регистрации (авторизации, сброса пароля) выводит файл wp-login.php.

  • /wp-login.php — авторизация
  • /wp-login.php?action=register — регистрация
  • /wp-login.php?action=lostpassword — сброс пароля

Для мультисайта в wp-login.php есть отдельные условия. Так, при переходе по ссылке /wp-login.php?action=register на мультисайте, WordPress сделает редирект на страницу /wp-signup.php. Во многих темах страница выглядит не очень привлекательно, поэтому мы сделаем свою собственную.

Файл wp-signup.php в теме Селена. Как и во многих других темах выглядит не очень опрятно.

Файл wp-signup.php в теме Селена. Как и во многих других темах выглядит не очень опрятно.

Основной сайт сети

По умолчанию, WordPress открывает страницу регистрации (wp-signup.php) на основном домене (сайте) сети. Тем не менее, можно сделать отдельную страницу регистрации для каждого сайта сети, даже если у них разные темы. Мы будем рассматривать случай, когда на всех сайтах сети есть своя собственная страница регистрации, но используется одинаковая тема и сайты различаются лишь языком. Если используются разные темы, потребуется написать больше кода.

functions.php?

Нет. Имя этого файла, кажется, упоминается в любой статье про WordPress. В нашем случае, с учетом того, что функционал регистрации рассчитан на несколько сайтов, имеет смысл вынести его в MU-плагины, которые загружаются при открытии любого сайта.

Лирическое отступление

Стоит отметить, что MU-плагины загружаются раньше обычных плагинов и до полной загрузки ядра WordPress, поэтому вызов некоторых функций может привести к фатальным ошибкам в PHP. Подобная «ранняя» загрузка имеет и свои плюсы. Скажем внутри любой темы нельзя цепляться к некоторым экшенам, которые срабатывают еще до загрузки файла functions.php из темы. Примером этого могут служить экшены из плагина Jetpack вида jetpack_module_loaded_related-posts (related-posts — название модуля) с помощью которых возможно отслеживать активность модулей в Jetpack. К этому экшену невозможно «прицепиться» из файла темы, потому что экшен уже сработал до загрузки темы — плагины загружаются раньше тем. Взглянуть на общую картинку порядка загрузки WordPress можно на странице Action Reference в кодексе.

Порядок в файлах

MU-плагины могут содержать любое количество файлов и любую стуктуру, которая покажется вам логичной. Я придерживаюсь примерно такой иерархии:

|-mu-plugins
|-|-load.php
|-|-|-selena-network
|-|-|-|-signup
|-|-|-|-|-plugin.php
|-|-|-|-|-...
|-|-|-|-jetpack
|-|-|-|-|-plugin.php

В файле load.php подключаются все необходимые «плагины» для нашей сети:

// Load Traslates for all addons
load_muplugin_textdomain ('selena_network', '/selena-network/languages/');

// Network Signup
require WPMU_PLUGIN_DIR . '/selena-network/signup/plugin.php';

// Another plugins
// require WPMU_PLUGIN_DIR ...

Внутри папки selena-network хранятся папки плагинов, в каждой есть свой plugin.php, которые мы и подключаем в load.php. Это дает гибкость и возможность быстро отключать и включать некоторые вещи.

Адрес страницы регистрации

Чтобы указать адрес страницы регистрации, используется фильтр wp_signup_location. Его можно найти внутри файла wp-login.php и именно он отвечает за редирект на wp-signup.php.

case 'register' :
	if ( is_multisite() ) {
		wp_redirect( apply_filters( 'wp_signup_location', network_site_url( 'wp-signup.php' ) ) );
		exit;

Добавим свою функцию в mu-plugins/selena-network/signup/plugin.php, которая будет отдавать адрес страницы регистрации на текущем сайте:

function selena_network_signup_page ($url) {
	return home_url () . '/signup/';
}
add_filter ('wp_signup_location', 'selena_network_signup_page', 99);

selena_network — префикс, который я использую в именах всех функций внутри MU-плагинов на своем сайте для избежания коллизий, его следует заменить на свой собственный уникальный префикс. Приоритет добавления фильтра 99, потому что некоторые плагины, например bbPress и BuddyPress могут перезаписать этот адрес на свой собственный (MU-плагины загружаются раньше, чем обычные плагины, см. выше). Обратите внимание, что используется home_url(), вместо network_site_url(), чтобы оставить посетителя на том же домене. В качестве адреса можно использовать любой URL.

Создание страницы

Теперь создадим страницу с адресом site.com/signup/ через обычный интерфейс, а в папке дочерней темы шаблон для нашей новой страницы — page-signup.php. Вместо слова «signup» можно использовать уникальный ID.

Внутри нового шаблона необходимо выполнить вызов функции selena_network_signup_main(), которая будет выводить форму регистрации.

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

wp-signup.php и wp-activate.php

Теперь займемся созданием функции, которая будет выводить форму регистрации. Для этого скопируем файлы wp-signup.php и wp-activate.php из корня WordPress в mu-plugings/selena-network/signup/ (и не забываем их подключить внутри mu-plugins/selena-network/signup/plugin.php). Дальнейшие манипуляции с файлами крайне сложно и долго описывать, поэтому прийдется сделать их самостоятельно. Я лишь опишу что именно надо сделать и опубликую исходные файлы своего проекта:

  1. В начале файла удалить все require, вызов функций и прочий код вне функций.
  2. Переименовать все функции, добавив к именам уникальные префиксы.
  3. Нижнюю часть кода wp-signup.php обернуть в функцию selena_network_signup_main и в ее самом начале написать global $active_signup;.
  4. Заменить верстку на свою собственную в нужных местах.

Пример рабочего wp-signup.php.

Внутри wp-activate.php необходимо сделать примерно тоже самое:

  1. Удалить весь код вне функций, обернуть верстку в отдельную функцию.
  2. Изменить верстку в местах, где это необходимо.

Пример рабочего wp-activate.php.

Файл wp-activate.php отвечает за страницу активации аккаунта. Как и со страницей регистрации для нее необходимо создать отдельный шаблон, внутри которого вызывать функцию из файла wp-activate.php.

Отправляем письма активации

Страница регистрации отправляет посетителю письмо со ссылкой на активацию аккаунта. По умолчанию этим занимается функция wpmu_signup_user_notification() из файла ms-functions.php. Ее функционал можно заимствовать для своей функции. Причина, по которой необходимо отказаться от использования этой функции — она отправляет ссылку активации аккаунта с wp-activate.php. «Выключить» же эту функцию можно с помощью фильтра wpmu_signup_user_notification отдавая по нему false (если этого не cделать, письмо активации будет отправляться дважды, окей, на самом деле два разных письма).

function armyofselenagomez_wpmu_signup_user_notification( $user, $user_email, $key, $meta = array() ) {
	// ...
	// Код из функции wpmu_signup_user_notification()
	wp_mail( $user_email, wp_specialchars_decode( $subject ), $message, $message_headers );
	return false;
}
add_filter( 'wpmu_signup_user_notification', 'armyofselenagomez_wpmu_signup_user_notification', 10, 4 );

В результате страница регистрации в теме Селена стала выглядеть намного чище и аккуратней.

Страница регистрации в теме Селена после всех манипуляций — чистая и аккуратная

Страница регистрации в теме Селена после всех манипуляций — чистая и аккуратная

Заключение

В интернете множество других не очень правильных способов того, как сделать тоже самое — редиректы Apache, AJAX-формы, которые не будут работать без Java Script и т. п. Все это мне не очень понравилось, поэтому я постарался сделать это максимально правильно на своем собственном сайте.

Замечу, что править файлы следует осторожно и стараться не сильно отходить от исходных, чтобы в дальнешйем, в случае если WordPress изменит файлы wp-signup.php и wp-activate.php, их проще было сравнивать между собой для поиска изменений.

Не забывайте смотреть в исходный код всех описанных выше функций, чтобы полностью разобраться с тем, что и как происходит внутри кода.

Бонус. Защита от спамеров

Даже самые маленькие сайты на WordPress часто подвергаются налету спам-регистраций. Можно писать бесконечные условия для фильтрации ботов, зачастую больше похожие на попытку создать искусственный интеллект 🙂 В случае мультисайта мне очень помог обычный редирект в Apache, с помощью которого при открытии /wp-signup.php и /wp-acitvate.php я попросил выдавать 404 (я не эксперт по настройке Apache, поэтому мои правила могут быть не очень правильными).

RewriteEngine On
RewriteBase /

RewriteRule ^wp-signup\.php - [R=404,L]
RewriteRule ^wp-activate\.php - [R=404,L]

# BEGIN WordPress
# Правила от WordPress по умолчанию не трогаем :)
# ...
# END WordPress

P. S. Я стараюсь максимально детально описывать некоторые сторонние вещи, потому что когда начинал я, порой некому было подсказать и объяснить многие вещи. Также я считаю, что подобные небольшие наводки на другие материалы кого-нибудь подтолкнут к изучению чего-то нового и расширению своей области знаний. В записях RewriteRule используются регулярные выражения, они совсем не сложные, например, символ ^ означает начало строки.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s