Настройка оборудования и программного обеспечения

Безнравственный signup php lang. Как создать собственную страницу регистрации в WordPress Multisite

Much of the websites have a registration form for your users to sign up and thus may benefit from some kind of privilege within the site. In this article we will see how to create a registration form in PHP and MySQL.

We will use simple tags and also we will use table tag to design the Sign-Up.html webpage. Let’s start:

Listing 1 : sign-up.html

Sign-Up

Registration Form
Name
Email
UserName
Password
Confirm Password


Figure 1:

Description of sing-in.html webpage:

As you can see the Figure 1, there is a Registration form and it is asking few data about user. These are the common data which ask by any website from his users or visitors to create and ID and Password. We used table tag because to show the form fields on the webpage in a arrange form as you can see them on Figure 1. It’s looking so simple because we yet didn’t used CSS Style on it now let’s we use CSS styles and link the CSS style file with sing-up.html webpage.

Listing 2 : style.css

/*CSS File For Sign-Up webpage*/ #body-color{ background-color:#6699CC; } #Sign-Up{ background-image:url("sign-up.png"); background-size:500px 500px; background-repeat:no-repeat; background-attachment:fixed; background-position:center; margin-top:150px; margin-bottom:150px; margin-right:150px; margin-left:450px; padding:9px 35px; } #button{ border-radius:10px; width:100px; height:40px; background:#FF00FF; font-weight:bold; font-size:20px; }

Listing 3 : Link style.css with sign-up.html webpage



Figure 2:

Description of style.css file:

In the external CSS file we used some styles which could be look new for you. As we used an image in the background and set it in the center of the webpage. Which is become easy to use by the help of html div tag. As we used three div tag id’s. #button, #sing-up, and #body-color and we applied all CSS styles on them and now you can see the Figure 2, how much it’s looking beautiful and attractive. You can use many other CSS styles as like 2D and 3D CSS styles on it. It will look more beautiful than its looking now.

After these all simple works we are now going to create a database and a table to store all data in the database of new users. Before we go to create a table we should know that what we require from the user. As we designed the form we will create the table according to the registration form which you can see it on Figure 1 & 2.

Listing 3 : Query for table in MySQL

CREATE TABLE WebsiteUsers (userID int(9) NOT NULL auto_increment, fullname VARCHAR(50) NOT NULL, userName VARCHAR(40) NOT NULL, email VARCHAR(40) NOT NULL, pass VARCHAR(40) NOT NULL, PRIMARY KEY(userID));

Description of Listing 3:

One thing you should know that if you don’t have MySQL facility to use this query, so should follow my previous article about . from this link you will able to understand the installation and requirements. And how we can use it.

In the listing 3 query we used all those things which we need for the registration form. As there is Email, Full name, password, and user name variables. These variable will store data of the user, which he/she will input in the registration form in Figure 2 for the sing-up.

After these all works we are going to work with PHP programming which is a server side programming language. That’s why need to create a connection with the database.

Listing 4 : Database connection

Description of Listing 4:

We created a connection between the database and our webpages. But if you don’t know is it working or not so you use one thing more in the last check listing 5 for it.

Listing 5 : checking the connection of database connectivity

Description Listing 5:

In the Listing 5 I just tried to show you that you can check and confirm the connection between the database and PHP. And one thing more we will not use Listing 5 code in our sing-up webpage. Because it’s just to make you understand how you can check the MySQL connection.

Now we will write a PHP programming application to first check the availability of user and then store the user if he/she is a new user on the webpage.

Listing 6 : connectivity-sign-up.php

Description of connectivity-sign-up.php

In this PHP application I used simplest way to create a sign up application for the webpages. As you can see first we create a connection like listing 4. And then we used two functions the first function is SignUP() which is being called by the if statement from the last of the application, where its first confirming the pressing of sign up button. If it is pressed then it will call the SingUp function and this function will use a query of SELECT to fetch the data and compare them with userName and email which is currently entered from the user. If the userName and email is already present in the database so it will say sorry you are already registered

If the user is new as its currently userName and email ID is not present in the database so the If statement will call the NewUser() where it will store the all information of the new user. And the user will become a part of the webpage.



Figure 3

In the figure 3, user is entering data to sign up if the user is an old user of this webpage according to the database records. So the webpage will show a message the user is registered already if the user is new so the webpage will show a message the user’s registration is completed.



Figure 4:

As we entered data to the registration form (Figure 4), according to the database which userName and email we entered to the registration form for sing-up it’s already present in the database. So we should try a new userName and email address to sign-up with a new ID and Password.



Figure 5

In figure 5, it is confirming us that which userName and email id user has entered. Both are not present in the database records. So now a new ID and Password is created and the user is able to use his new ID and Password to get login next time.

Conclusion:

In this article we learnt the simplest way of creating a sign up webpage. We also learnt that how it deals with the database if we use PHP and MySQL. I tried to give you a basic knowledge about sign up webpage functionality. How it works at back end, and how we can change its look on front end. For any query don’t hesitate and comment.

Привет всем читателям!

Сегодня мы рассмотрим довольно важную тему, которая выдвигается многими работодателями, а именно мультиязычность.

Что же я имел ввиду, говоря о мультиязычности. Ну, наверняка каждый из моих достопочтенных читателей не раз видели крутые порталы и между всем сбродом информации находили две маленькие иконки, преимущественно со всем известным звёздно-полосатым и родным бело-сине-красным флагами. Безусловно, после нажатия на одну из них привычная нам русская речь превращалась в буржуйский language (), или наоборот. Но задавали ли вы себе когда-либо вопрос о том, как это всё делается. Что ж, именно об этом я и буду вести речь.

Сразу скажу, что для работы с тем материалом, который будет здесь изложен вам понадобиться поддержка РНР не ниже 4.39.

Итак, как вы знаете, содержание нашего сайта разделяется на динамическое и статическое. К статическому содержанию мы отнесём то, что не будет изменять своё значение в процессе работы (ключевые слова, текст ошибок, и прочая белиберда). С этого мы и начнём. Но давайте проанализируем, как именно мы будем изменять язык данного текстового значения. Надеюсь, никто не предложил воспользоваться исключениями, ибо это настолько нерационально, что нерациональней и быть не может. Вместо этого я предлагаю воспользоваться константами (о типе данных читайте на php.net). Мы просто будем объявлять служебное слово, которое в зависимости от значения языка соответственно будет менять и своё значение. Как мы это сделаем? Да как и все, создадим два (к примеру) разных файла, имена которых будут носить такой шаблон:

Язык_map.php;

Как вы уже поняли вместо слова `язык` мы подставим значение, характеризующее данный язык. В нашем случае мы будем использовать двухсимвольный код языка (ru, en, ua, pl и т.д.).

Что ж теорию выяснили теперь давайте, применим наши знания на практике. Создаём два файла. Я создал файлы с английским переводом и русским, а как создадите вы это уже на ваш вкус.

Файл: en_map.php

Файл: ru_map.php

Итак, на мой взгляд, ничего сложного нет, и всё написанное подчиняется самым банальным законам РНР. Сначала мы делаем проверку, не были ли константы уже объявлены, если были, то не объявляем, в противном же случае объявляем.

Это была лёгкая часть, теперь давайте перейдём к более сложной теме - к переводу динамической части.

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

Но опять возвращаясь к дилемме о "Дизайнерах и Программистах" нужно опять упомянуть что такой сайт должен полностью быть, так сказать "Что Видишь То И Получишь", иначе нельзя. Поэтому я постараюсь сделать всё так, чтобы оно не вызывало нервного тика у программистов, и могло удовлетворить дизайнеров (имеется ввиду юзабилити).

Итак, долой пустые слова и вперёд на Берлин. Мы начнём с теории. Итак, как же мы будем различать языки у динамического содержания, которое в лучшем случае удаляется, изменяется, а то и чего хорошего вообще накроется. Константами тут никак не обойтись, что же делать?

Я уже слышу витающие вокруг вас мысли.

Лично когда я пытался воплотить это в жизнь, то сначала я это сделал самым нерациональным способом, а именно для перевода статей разделил поля в таблице, которые подлежали переводу надвое (то есть, создал поле_eng и поле_ru) таким образом, и так большие по объёму таблицы превратились просто в непристойно огромные. Поэтому я начал искать альтернативу, и не поверите, нашёл её. Чувствуете уже теплее, да, скоро мы подойдём к самому горячему. Я нашёл выхода из этой ситуации, и сейчас намерен объяснить на пальцах его вам, и то поймёте ли вы его или нет, будет зависеть от вас. Сначала давайте, согласуем все детали.

Для начала нам нужна, будет таблица, в которой будут размещаться данные для перевода. Скажем у нас есть таблица `articles` в которой будут размещены некоторые статьи, и они должны иметь, скажем, два перевода, но один обязательно. Нас будут интересовать лишь два ключевых, в нашем случае, поля: название, описание. Мы будем осуществлять структурирование текста таким образом:

<%eng%>Английский вариант статьи <%ru%>Русский вариант статьи

После строка ввиде комбинации из этих двух структур и будет добавляться в поля `title` и `description` таблицы `articles`.

Данный способ будет заключаться в поиске первого вхождения открывающего ключевого слова (допустим <%eng%>), после мы найдём первое вхождение закрывающего ключевого слова. Но нужно не забывать что нам нужно не именно вхождение, а длина конструкции. В первом случае мы к первому вхождению открывающей конструкции будем добавлять длину конструкции, вторым шагом будет нахождение длины закрывающей конструкции. Но вы спросите: <Как же мы получим текст?>.

Воспользовавшись функцией substr(). В качестве первого параметра будет сам текст, в качестве второго длина открывающей конструкции, в качестве третьего (самое интересное) разница между первым вхождением закрывающей конструкции и длинной текста. Да, понимаю это не так легко, но это нужно понять. Поэтому мы сейчас это и проделаем на практике. Я создал функцию, которая будет выделять текст между ключевыми тегами. Она будет принимать три параметра: текст для разбора, язык по которому нужно проводить парсинг, массив конструкций.

","<%/","%>")) { $start_tag=strpos($data,$delimiters.$lang.$delimiters)+ strlen($delimiters.$lang.$delimiters); $count=(strpos($data,$delimiters.$lang.$delimiters)-strlen($data)) $data=substr($data,$start_tag,$count); if(trim($data)==""){ $data=NOT_ENTERED; } return $data; } ?>

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

Так, с перебором выяснили, но теперь перед нами предстаёт новая задача, компиляция обычного текста в спецформатированую строку. Это уже намного проще, и если вы достаточно хорошо знаете РНР, то вы без труда напишите такую функцию, а если пока плаваете, то прошу в кабинет.

Алгоритм не сложный и заключён в том, чтобы подставить в все языковые конструкции в одну строку. Сначала я в порывах лени я хотел ограничить скрипт определённым числом языков (так его воплотить легче), однако после одумался и получил вот что:

","<%/","%>")) { if(!is_array($data)) { die(PARAM_CHECK_ERROR); } $data=""; $temp=""; $count=0; foreach($data as $k=>$v) { if(!is_string($k)) { break; } $count++; if($count>1 & $temp=$k) { die(ERROR_CONSTRUCTION_COUNT); } $temp=$k; $data.=$delimiters.$k.$delimiters.$v.$delimiters.$k.$delimiters; } return $data; } ?>

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

"индификатор языка"=>"текст";

После мы делаем проверку, что если полученный параметр не массив то <пока Вася!>.

Если же это всё же массив то конечно делаем его перебор, и на место языка в конструкции ставим ключ данного элемента ассоциативного массива, а на место текста безусловно сам текст а то есть значение переменной $v. После сливаем все данные в одну строку. Но я забыл упомянуть об одной важной детали, а другими словами о довольно большом куске текста. Сначала перед циклом мы объявили три переменные: data, temp, count;

Переменная count- это количество итераций цикла, и с каждым следующим кругом цикла счётчик увеличивается. Переменная data- это будущая результирующая строка, в которую будут сливаться все языковые конструкции. Но более интересны переменные count и temp. Для чего они нужны? Ну, наверное, большинство уже догадались, прочтя исходник, но тем до кого ещё не <дошло> я поясню. Это делается для проверки того, что языковая конструкция не была повторена более раза. Для этого мы и объявили переменную count. Так как её значение по умолчанию равно нулю, то мы проверяем, что цикл был выполнен хотя бы раз, поскольку если мы этого не сделаем то, выйдет что-то подобное 2=2 или 0=0, ведь значение $k ещё не успело измениться. Так как в первый раз проверка будет игнорироваться, мы после проверки присваиваем значение переменной $temp. Это делается так же не просто так. При первой итерации всё пойдёт нормально, но ведь если мы всё же присвоили значение до проверки, то проверка делала бы проверку, о которой уже упоминалось (2=2, 3=3 и т.д.). Вот зачем мы делаем именно так.

Теперь как логическое завершение мы создадим небольшой сайт, где и будет применяться всё вышеизложенное:

","<%/","%>")) { $data=substr($data, (strpos($data,$delimiters.$lang.$delimiters)+ strlen($delimiters.$lang.$delimiters)), (strpos($data,$delimiters.$lang.$delimiters)-strlen($data))); if(trim($data)=="") { $data=NOT_ENTERED; } return $data; } function compilateLanguageString($data, $delimiters=array("<%","%>","<%/","%>")) { if(!is_array($data)) { die(PARAM_CHECK_ERROR); } $data=""; $temp=""; $count=0; foreach($data as $k=>$v) { if(!is_string($k)) { break; } $count++; if($count>1 & $temp=$k) { die(ERROR_CONSTRUCTION_COUNT); } $temp=$k; $data.=$delimiters.$k.$delimiters.$v.$delimiters.$k.$delimiters; } return $data; } //Не забываем о <статике> if(!isset($_GET["lang"])) { setcookie("lang",$_GET["lang"]); header("Location: index.php?module=home"); } if(isset($_COOKIE["lang"])) { include $_COOKIE["lang"]."_map.php"; } else { include "ru_map.php": } if(isset($_POST["add"])) { $description=compilateLanguageString(array($_POST["description_en"],$_POST["description_ru"])); $title=compilateLanguageString(array($_POST["titlte_eng"],$_POST["title_ru"])); //Процесс добавления в базу } echo""; echo""; echo""; $title=($_SERVER["REMOTE_ADDR"]=="127.0.0.1")? ADMIN_WELCOM: "Гостям- Здрасте!"; echo $title; echo""; echo""; echo"": echo""; $conn_id=@mysql_connect("localhost","root",""); @mysql_select_db("somedatabase"); $q=@mysql_query("SELECT title, description FROM `articles` LIMIT 0,1",$conn_id); if(@mysql_ num_rows($q)==0){ ARTCILES_NOT_FOUNDED; } else { $row=@mysql_fetch_array($q); $title=subTextByLang($row["title"],$lang); $description=subTextByLang($row["description"],$lang); echo"

": echo""; echo""; echo""; echo"
".ARTICLE_TITLE_TEXT."". $title."
". ARTICLE_DESCRIPTION_TEXT."
".$description."
"; } @mysql_close($conn_id); //Это ещё полбеды, теперь нужно создать форму для добавления статьи echo"
"; echo""; echo""; echo""; echo""; echo""; echo""; echo""; echo""; echo"
".ARTICLE_TITLE_TEXT. "(EN):
".ARTICLE_TITLE_TEXT." (RU):
". ARTICLE_DESCRIPTION_TEXT."(EN):
"; echo""; echo"
". ARTICLE_DESCRIPTION_TEXT."(RU):
"; echo""; echo"
"; echo"
"; ?>

Что ж вот и всё. Однако в скрипте есть одно "но", автор не может через форму добавить более двух вариантов перевода. Не буду, как остальные автора, что сделал это для вашей тренировки, поскольку если честно то когда я дошёл до этого места у меня уже голова почти не варила, поэтому я и оставляю это на ваших плечах. Поверьте, вариантов решения полно, и я очень надеюсь, что вы его найдёте. Относительно функций, то не могу сказать на все 100% что они не вызовут сбоя но фатальных ошибок быть не должно, хотя всякое бывает. Но я уверен более чем на 60% что синтаксис нарушен, так как я не тестировал примеры. А вот здесь для вас действительно хорошая тренировка ведь ловля "блох" очень полезное занятие!

Что ж, я считаю, что на этом статью можно окончить. Если у вас не будет получаться, не сгоняйте зло на ваш бедный компьютер, на клавиатуру, и тем более на разработчиков такого замечательного языка как РНР, смело, все свои неудачи адресуйте в мою сторону. Я не думаю, что мне от этого станет хуже, а вот вам будет на кого согнать злость.

You"ve made a good start, but the switch statement in userLanguage() just doesn"t feel right from an Object orientated perspective:

A class called Language should represent a single language which is generic enough to fit all cases: however at the moment, whatever language it represents, it has the definitions of all of them just jammed into that one method.

Is it maintainable? Not really, no. At the moment you have two languages, which I assume you know. However, should you ever want to translate it into another language (perhaps using another Charset, you"re going to run into issues of space in the file, saving the file correctly, and merging in translations provided by other people for your site.

As to whether to use databases, abstract classes et cetera: You may want to, though there are other solutions.

Solution 1: Simple Configuration File

parse_ini_file() is a very powerful little tool that does exactly what you expect. Using a simple file like this which we"ll call en.ini :

PAGE_TITLE = My website page title HEADER_TITLE = My website header title SITE_NAME = My Website SLOGAN = My slogan here HEADING = Heading MENU_LOGIN = Login MENU_SIGNUP = Sign up MENU_FIND_RIDE = Find Ride MENU_ADD_RIDE = Add Ride MENU_LOGOUT = Logout

You can simply use: parse_ini_file("en.ini") to return an array exactly as in your switch statement, which will be much easier for other (non-programmers) to read and write for you. And if you were to then continue naming the files with this style, you could reduce userLanguage() to something like:

Public function userLanguage() { $file = "/path/to/language/config/" . $this->UserLng . ".ini"; if(!file_exists($file)) { //Handle Error } return parse_ini_file($file); }

Solution 2: Abstract class

As your array is basically acting as getter methods, an abstract Language class should have all the language components you need in it, like so:

Interface Language { public function getPageTitle(); public function getHeaderTitle(); public function getSiteName(); public function getSlogan(); public function getHeading(); public function getMenuLogin(); public function getMenuSignup(); public function getMenuFindRide(); public function getMenuAddRide(); public function getMenuLogout(); }

Though the interface is small, implementing it may produce a big file, though it would arguably be clearer than the array style:

Class English implements Language { public function getHeaderTitle() { return "My website header title"; } public function getHeading() { return "Heading"; } // etc... }

Alternative

Alternatively, you could combine these styles and have a singleton Language with getter methods accessing that array, i.e.:

Class Language { private $languageArray; private $userLanguage; public function __construct($language) { $this->userLanguage = $language; $this->languageArray = self::userLanguage(); } private static function userLanguage() { $file = "/path/to/language/config/" . $this->userLanguage . ".ini"; if(!file_exists($file)) { //Handle Error } return parse_ini_file($file); } public function getPageTitle() { return $this->languageArray["PAGE_TITLE"]; } public function getHeaderTitle() { return $this->languageArray["HEADER_TITLE"]; } //etc... }

Which will provide the benefits of both. Personally though, unless you"re planning on adding more languages in the very near future, I believe solution #2 would suit you best.

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

В обычной установке 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 . Во многих темах страница выглядит не очень привлекательно, поэтому мы сделаем свою собственную.

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

По умолчанию, 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-activate.php необходимо сделать примерно тоже самое:

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

Файл 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 - RewriteRule ^wp-activate\.php - # BEGIN WordPress # Правила от WordPress по умолчанию не трогаем:) # ... # END WordPress

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

Advertisements

Позволяет использовать одну установку WordPress для нескольких сайтов одновременно. При этом каждый сайт получает свои собственные таблицы в базе данных с уникальным префиксом.

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

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

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

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

Помимо регистрации обычных пользовательских аккаунтов на ней можно создать и новый сайт, если суперадминистратор включил такую возможность в настройках сети (Network Admin → Settings → Network Settings).

В большинстве тем страница регистрации выглядит не совсем хорошо. Многие темы оформления используют CSS-фреймворки, например, Bootstrap, и собственные специфичные классы для стилизации разных элементов на страницах, поэтому тяжело написать единый HTML, который подойдет всем.

Но не стоит отчаиваться, если страница выглядит неопрятно. Файл wp-signup.php отличная вещь на первых порах, когда нет времени прорабатывать каждую деталь сайта — можно сосредоточиться на других более важных страницах и контенте.

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

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

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

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

Альтернатива functions.php

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

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

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

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

// Загрузка переводов для MU-плагинов load_muplugin_textdomain("selena_network", "/selena-network/languages/"); // Функционал для страницы регистрации require WPMU_PLUGIN_DIR . "/selena-network/signup/plugin.php"; // Еще один плагин // require WPMU_PLUGIN_DIR ...

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

Страница регистрации

Разобравшись с тем, где и как мы будем писать код, можно переходить к созданию страницы регистрации.

Создадим страницу с адресом example.org/signup/ через обычный интерфейс. В качестве адреса можно использовать любой URL, который покажется подходящим для вашего проекта.

Редирект на нужную страницу регистрации

Чтобы WordPress узнал о нашей новой странице регистрации и производил редирект именно на нее, при клике на ссылку «Зарегистрироваться», используется фильтр 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; // ...

Как вы помните, по умолчанию, страница регистрации открывается на основном домене сети. Именно поэтому здесь используется network_site_url() .

Добавим свой обработчик к фильтру в 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() , отдает адрес текущего сайта, а не главного сайта сети.

Функционал wp-signup.php

Файл wp-signup.php содержит большое количество функций и кода. Чтобы увидеть картину в целом можно воспользоваться сворачиванием кода. Как правило, по-английски это называется «code folding».

В самом начале файла с 1 по 80 строчку (в версии 4.1.1) производятся различные проверки и вывод «старта» страницы с помощью get_header() .

Далее объявляются множество методов и перед тем, как мы начнем работать с ними, стоит разобраться что делает каждая функция. Внутри многих из них часто используются другие функции с префиксом wpmu_ , все они объявляются в файле wp-includes/ms-functions.php . Этот раздел тяжело понять не видя код самостоятельно. Ниже небольшое описание основных функций на случай, если у вас возникнут затруднения.

  • wpmu_signup_stylesheet() — вывод дополнительного CSS на странице регистрации.
  • show_blog_form() — поля для регистрации сайта (адрес, название видимость для поисковых систем).
  • validate_blog_form() — проверка введенного адреса сайта и названия с помощью wpmu_validate_blog_signup() .
  • show_user_form() — поля для регистрации пользователя (логин и адрес эл. почты).
  • validate_user_form() — проверка введенного логина и адреса эл. почты с помощью wpmu_validate_user_signup() .
  • signup_another_blog() — поля для регистрации новых сайтов с помощью show_blog_form() для пользователей, которые уже зарегистрированы на сайте.
  • validate_another_blog_signup() — проверяет адрес сайта и название с помощью validate_blog_form() .
  • signup_user() — основная функция для вывода полей страницы регистрации.
  • validate_user_signup() — проверяет логин и адрес эл. почты с помощью validate_user_form() .
  • signup_blog() — поля для ввода адреса, названия и видимости сайта (второй шаг регистрации) с помощью show_blog_form() .
  • validate_blog_signup() — проверяет логин, адрес эл. почты, адрес и название сайта.

В самом низу файла wp-signup.php (со строчки 646 в версии 4.1.1) основная логика работы страницы регистрации, которая использует все выше описанные методы. Эта часть кода не вынесена в функцию. В конце вызывается get_footer() .

Копируем функционал wp-signup.php

Далее будет описана процедура копирования wp-signup.php в MU-плагины и внесению изменений в «форк». Возможно, это может показаться не самым правильным путем. Вместо этого можно с нуля написать свои функции для проверки и вывода форм используя классы, а не обычные функции. На мой взгляд в wp-signup.php уже есть вся необходимая логика для нашей страницы, остается лишь внести небольшие изменения.

При обновлении WordPress время от времени меняется и wp-signup.php , но это не значит что при каждом релизе придется синхронизировать свой «форк». Функции внутри wp-signup.php по сути занимаются лишь выводом HTML, проверкой данных, созданием учетных записей и сайтов занимаются методы с префиксом wpmu_ , объявленные в ms-functions.php .

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

Require WPMU_PLUGIN_DIR . "/selena-network/signup/wp-signup.php";

Удалим из самого начала скопированного файла все require и ненужные проверки. В версии 4.1.1 это весь код с 1 по 80 строчку.

Теперь мы готовы создать главную функцию для вывода формы регистрации. Для этого всю логику со строчки 646 и до самого конца файла перенесем в функцию c названием selena_network_signup_main . В самом конце удалим два лишних закрывающих

(строчки 722 и 723), а также вызов get_footer() .

В только что созданной selena_network_signup_main() в самом начале объявим глобальную переменную active_signup , которую используют все остальные методы из этого файла. И добавим вызов события before_signup_form , которое мы удалили из самого начала файла.

Function selena_network_signup_main() { global $active_signup; do_action("before_signup_form"); // ... }

Теперь остается лишь изменить верстку во всех местах где это необходимо и страница регистрации готова.

Вывод формы регистрации

Здесь есть как минимум два варианта. Более удобный способ — создать шорткод и разместить его на странице через обычный редактор.

// Создаем шорткод network_signup add_shortcode("network_signup", "selena_network_signup_main");

Второй вариант — создать в папке дочерней темы шаблон страницы page-signup.php . Вместо слова «signup» можно использовать уникальный ID, присвоенный странице. Внутри шаблона добавить необходимую верстку и сделать вызов selena_network_signup_main() в нужном месте.

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

Страница активации

По умолчанию WordPress условно делит процесс регистрации в Multisite на два шага — заполнение формы на сайте и активация аккаунта при переходе по ссылке отправленной в электронном письме. После того, как вы заполните форму, созданную в предыдущем разделе, WordPress отправляет письмо с небольшой инструкцией и ссылкой для активации аккаунта.

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

Создадим страницу example.org/activate/ через обычный интерфейс. В качестве адреса используйте любой URL, который покажется вам подходящим.

Скопируем файл wp-activate.php к себе в MU-плагины и подключим его в mu-plugins/selena-network/signup/plugin.php .

Require WPMU_PLUGIN_DIR . "/selena-network/signup/wp-activate.php";

Внутри не так много содержимого, в отличие от wp-signup.php . Файл выполняет единственную операцию — активирует аккаунт, если получен верный ключ и выводит сообщение об ошибке или успешном выполнении операции.

Удалим все ненужные проверки и require — с 1 по 69 строчку в WordPress 4.1.1. В самом конце уберем вызов get_footer() . Оставшееся содержимое перенесем в функцию selena_network_activate_main() .

Интересно заметить, что здесь перед загрузкой WordPress (wp-load.php) объявлялась константа WP_INSTALLING . Ее наличие заставляет WordPress не загружать плагины.

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

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

Письма активации с правильными ссылками

Страница активации готова к работе, но WordPress не знает о ней и по прежнему будет отправлять письма активации со ссылкой на wp-activate.php . В отличие от wp-signup.php здесь нет фильтра, который бы позволил изменить адрес. Вместо этого нужно написать свою функцию, которая будет отправлять письма с правильными ссылками.

В момент заполнения и отправки формы на странице регистрации WordPress вызывает wpmu_signup_user () или wpmu_signup_blog () в зависимости от типа регистрации. Обе функции создают новую запись в таблице wp_signups заполняя ее необходимым содержимым, среди которого есть и ключ активации аккаунта.

После, в зависимости от функции, вызывается wpmu_signup_user _notification() или wpmu_signup_blog _notification() . Обе функции имеют схожий функционал — генерируют и отправляют письмо со ссылкой активации, но принимают разные аргументы. В обоих есть фильтры для «перехвата» события.

If (! apply_filters("wpmu_signup_user_notification", $user, $user_email, $key, $meta)) return false;

Для активации аккаунтов с созданием блога:

If (! apply_filters("wpmu_signup_blog_notification", $domain, $path, $title, $user, $user_email, $key, $meta)) { return false; }

Остается лишь написать свои обработчики, внутри которых отправлять письма через wp_mail() , а в самом конце обязательно отдавать false , чтобы WordPress не отправил письмо активации дважды — одно ваше, другое — письмо по умолчанию со ссылкой на wp-activate.php .

Function selena_network_wpmu_signup_user_notification($user, $user_email, $key, $meta = array()) { // Генерируем заголовок, текст и заголовки письма // ... // Отправляем письмо или добавляем Cron-задачу для отправки письма wp_mail($user_email, wp_specialchars_decode($subject), $message, $message_headers); // Отдаем false, чтобы WordPress не отправил письмо активации дважды return false; } add_filter("wpmu_signup_user_notification", "selena_network_wpmu_signup_user_notification", 10, 4);

Если вы отправляете письма через SMTP-сервер или количество регистраций очень велико, следует задуматься о том, чтобы не отправлять письма мгновенно. Вместо этого можно добавлять Cron-задачи с помощью WordPress Cron .

Закрываем доступ к wp-signup.php и wp-activate.php

Создав свои собственные страницы регистрации и активации, может потребоваться закрыть «оригиналы». Например, если на странице регистрации есть дополнительные поля, которые необходимо обязательно заполнить. Также многие WordPress сайты подвергаются спам-регистрациям.

Решить две проблемы одним действием можно попросив Apache отдавать 404 в случае попытки открытия этих страниц. Для этого нужно лишь прописать пару дополнительных RewriteRule в ваш файл-конфигурацию или.htaccess .

RewriteEngine On RewriteBase / # Знание регулярных выражений никогда не будет лишним:) RewriteRule ^wp-signup\.php - RewriteRule ^wp-activate\.php - # BEGIN WordPress # Правила от WordPress по умолчанию не трогаем:) # ... # END WordPress

Заключение

Для этой и многих других «проблем» связанных с WordPress в интернете есть множество решений. Например, для создания страниц регистрации и активации некоторые предлагают переписывать оригинальные wp-signup.php и wp-activate.php . Этого не стоит делать, потому что в случае обновления WordPress вы потеряете все изменения, внесенные в файлы, а также не сможете, проверить целостность ядра с помощью .

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

P.S.

Для автоматического назначения разных ролей новым пользователям можно использовать плагин Multisite User Management .

Если у вас возникли вопросы или трудности во время создания страниц регистрации и активации после прочтения статьи, оставьте комментарий и мы обязательно ответим.

27.03.2015 27.03.2015

WordPress разработчик. Любит порядок во всем и разбираться в новых инструментах. Вдохновлен архитектурой компонентов Symfony.

  • Понравилась статья? Поделитесь с друзьями!
    Была ли эта статья полезной?
    Да
    Нет
    Спасибо, за Ваш отзыв!
    Что-то пошло не так и Ваш голос не был учтен.
    Спасибо. Ваше сообщение отправлено
    Нашли в тексте ошибку?
    Выделите её, нажмите Ctrl + Enter и мы всё исправим!
    Похожие советы