воскресенье, 3 февраля 2013 г.

Регистрация и авторизация в WordPress

Яндекс.ДиректВсе объявленияВидеокурс по PHP Бесплатный Видеокурс по созданию PHP-сайта с нуля. Реальный пример! srs.myrusakov.ru Уроки wordpress в видеоформате 37-минутный видеокурс научит тебя создавать сайт на Wordpress. Бесплатно! kalsin.ru 
Приветствую вас, дорогие друзья. Настало время снова окунуться в мир программирования для WordPress.
В предыдущих публикациях мы уже поговорили о следующих аспектах данной CMS:
В данной статье речь пойдет о регистрации и авторизации в WordPress.
Не секрет, что WordPress позволяет работать с различными группами пользователей, а не только с одним администратором. Данная особенность позволяет реализовать вполне сносный функционал регистрации и авторизованного доступа к тому или иному контенту (если уж по какой-то причине так нужно).

Думаю все знают, что разрешение на регистрацию новых пользователей выдает администратор, ставя галочку в настройках админки WordPress (Параметры→Общие).

Включение регистрации пользователей в WordPress
Рис. 1. Включение регистрации новых пользователей в админке WordPress.
Теперь пользователи смогут переходить на страницу http://vas_domen.ru/wp-login.php?action=register и наблюдать там стандартную форму регистрации WordPress.
Стандартный функционал регистрации в WordPress
Рис. 2. Стандартная форма регистрации WordPress.
Если регистрацию в админке вы не разрешили (см. рис. 1), то и форма регистрации вам не отобразится. Вместо нее вы увидите сообщение о невозможности регистрироваться на данном блоге.
Стандартная процедура регистрации в WordPress организована довольно грамотно (если не считать запроса имени пользователя, он же login, при регистрации; мы то с вами знаем, что вполне достаточно только адреса эл. почты). После проверки на занятость другим пользователем указываемого логина и e-mail, WordPress отправит валидационное письмо и проверит правильность введенного при регистрации адреса эл. почты. Все круто и правильно.
Для авторизации достаточно перейти по адресу http://vash_domen.ru/wp-login.php. Вы увидите стандартную форму авторизации (видели вы ее уже сто раз наверное, когда в свой блог логинились).
Форма авторизации WordPress
Рис. 3. Стандартная форма авторизации WordPress.
Есть даже стандартная процедура восстановления пароля. Перейдите по ссылке http://vash_domen.ru/wp-login.php?action=lostpassword и вы увидите форму грамотного функционала восстановления.
Форма восстановления пароля WordPress
Рис. 4. Стандартна форма восстановления пароля WordPress.
Уж не знаю, зачем я рассказываю эти банальности. Они всем известны? Тогда будем считать, что для разогрева.
Чем мне не нравится стандартный функционал регистрации/авторизации в WordPress? — Да, видимо, тем что на нормальных сайтах регистрация и авторизация выглядит немного по-другому.
Ну во-первых, на нормальных сайтах нет логотипа WordPress в формах регистрации/авторизации. С этой проблемой, кстати, можно легко бороться. Вот тут процедура подробно описана. Суть сводится к цеплянию на хук login_head вывода стилей для #login h1 a. Обратите внимание на директиву !important в перечислении свойств стиля. Именно благодаря этой директиве наложенные вами стили считаются наиболее приоритетными.
По аналогии с приведенным примерам на странице авторизации/регистрации можно наворатить стилями, все, что вашей душеньке будет угодно.
Что такое хук и как на него цеплять функции вы сможете узнать из моего видеокурса по разработке плагина для WordPress.
С детским садом закончили, переходим к серьезным вещам. На нормальном сайте обычно форма авторизации и регистрации вписывается в дизайн сайта, а не располагается на отдельных страницах.
Впишем форму регистрации в дизайн сайта
С регистрацией пользователя будет много мороки из-за необходимости верифицировать указанный при регистрации e-mail. Я решил эту проблему следующим тернистым путем:
  • Создал отдельную таблицу в БД для хранения имени пользователя, e-mail и пароля (генерируется автоматически). В этой таблице будут храниться данные, указанные пользователем в регистрационной форме до верификации адреса эл. почты. Также в этой таблице будет храниться проверочный код (зачем он нужен, станет понятно дальше).
  • В форму регистрации пользователь вводит логин и e-mail. Логин и e-mail валидируются на предмет совпадения с данными уже существующих пользователей WordPress. Ну и естественно проверяется ввел ли пользователь хоть что-то в поля «Логин» и «E-mail», а также соответствует ли введенный текст регулярному выражению для адреса эл. почты.
  • Если валидация прошла успешно, на почту указанную при регистрации уходит сообщение, содержащее проверочную ссылку.
  • Если пользователь перешел по ссылке, то стандартным методом добавления нового пользователя wp_create_user($user_name, $password, $user_email) происходит сохранение нового пользователя уже в стандартной таблице пользователей WordPress.
Видеоурок. Как сделать свою регистрацию пользователей в WordPress
Бонусом в видеоуроке показано как сделать валидацию имени пользователя и адреса эл. почты. Продемонстрированный подход годится на все случаи жизни.
Скачать плагин, демонстрируемый в видеоуроке (5.49 кБ).
Листинг 1. HTML-код формы регистрации, демонстрируемый в видеоуроке.
1<div>
2     <form action="" method="get" id="m_reg_user_form">
3          <div>
4               <label for="m_user_name">Имя:</label>
5          </div>
6          <div>
7               <input type="text" name="m_user_name" id="m_user_name">
8          </div>
9          <div>
10               <label for="m_user_email\">Эл. почта:</label>
11          </div>
12          <div>
13               <input type="text" name="m_user_email" id="m_user_email">
14          </div>
15          <div>
16               <input type="submit" name="m_regiser_usr_btn" value="Зарегистрироваться">
17          </div>
18     </form>
19</div>
В качестве дополнительных плюшек можно добавить проверку разрешения регистрации в админке (см. рис. 1). Проверить можно функцией get_option('users_can_register'). Если функция вернет TRUE, то регистрироваться можно.
Еще я бы сделал функцию в плагине, отвечающую за вывод формы регистрации, чтобы она выводилась именно там где нужно, а не болталась в посте без надобности. Но это уже в следующий раз.
Думаю имеет смысл показывать форму регистрации только не авторизованным пользователям. Проверять авторизован пользователь или нет позволяет функция is_user_logged_in(). Она вернет TRUE если пользователь имеет статус авторизованного.
После перехода пользователя по валидационной ссылке из e-mail, у вас может возникнуть законное желание сразу его авторизовать. Это можно сделать следующим образом.
Листинг 2. PHP-код насильственной авторизации пользователя в WordPress.
1$creds = array();
2$creds['user_login'] = $email_check->user_name;
3$creds['user_password'] = $email_check->password;
4$creds['remember'] = false;
5$user = wp_signon($creds, false);
Как вы понимаете, авторизация происходит благодаря методу wp_signon.
Раз уже речь зашла об авторизации, то давайте поговорим, как это сделать без насилия.
Авторизация пользователя WordPress своей формой
Точно также, как и в случае регистрации, я запросто могу представить себе, что вам захотелось прикрутить свою собственную форму авторизации, а не гонять пользователя на рис. 3.
Используйте HTML-код, представленный ниже. Единственное, что нужно сохранить, это атрибуты name и адрес в атрибуте action тега form (иначе WP не поймет, что вы от него хотите).
Листинг 3. PHP-код формы авторизации. Можно использовать в плагине.
1// Получаю адрес текущей страницы
2$current_url = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
3
4// В перемненную сохраняю HTML-код формы авторизации. Переменную можно вывести тогда, когда потребуется отобразить форму авторизации.
5$login_form = "
6<form action=\"".wp_login_url($current_url)."\" id=\"loginForm\" method=\"post\">
7     <div class=\"field\">
8          <label for=\"login\">Имя пользователя:</label>
9     </div>
10     <div class=\"input\">
11          <input type=\"text\" name=\"log\" value=\"\"  id=\"login\">
12     </div>
13     <div class=\"field\">
14          <label for=\"pass\">Пароль:</label>
15     </div>
16     <div class=\"input\">
17          <input type=\"password\" name=\"pwd\" value=\"\" id=\"pass\">
18     </div>
19     <div class=\"rememberme\">
20          <input name=\"rememberme\" type=\"checkbox\" id=\"rememberme\" value=\"forever\"> <label for=\"rememberme\">Запомнить меня</label>
21     </div>
22     <div class=\"submit\">
23          <input name=\"submit\" type=\"submit\" value=\"Войти\">
24     </div>
25     <input type=\"hidden\" value=\"$product_id\" name=\"product_id\">
26</form>
27";
Атрибут action тега form содержит функцию wp_login_url. Она на столько замечательная, что позволяет в качестве атрибута передать адрес, на который пользователя вернет после авторизации. Это может быть адрес данной страницы (как в листинге 3) или URL личного кабинета — решать вам.
На этом пока все. До встречи в следующих видеоуроках.
P.S.: На правах саморекламы. А вы знаете, что я разработал замечательный плагин, позволяющий продавать инфотовары с блога на WordPress?
С уважением, Андрей Морковин.

  • Павел Свернуть
    огромное спасибо за статью , только 1 маленькое замечание: на моем достаточно выше стандартного мониторе (1680х1050) видео смотрится достаточно плохо , шрифт еле вижу :(
    Снимайте пожалуйста половину монитора или как раньше приближайте к нужному участку. Еще раз Спасибо!

  • Видно, конечно, плоховато. Но читабильно. Вы в HD-качестве смотрите?

  • Павел
    да , HD 720p , вот скриншот http://clip2net.com/clip/m0/13...
    может у меня что то не то или не так настроено?

  • Александр
    Подтверждаю проблему Павла.
    На Full-HD мониторе (iMac 21.5") даже при просмотре в качестве 720p шрифты очень плохо читаются, всё "мыльное"-размытое.

  • alexriz
    У меня на 17" на видео 720p тоже ничего не видно((слишком мелко получается


  • jhekasoft
    HTML-код в строке PHP — это не очень (с экранированием который).  Можно использовать ob_start(), ob_get_contents().
    А в нормальных фреймворках вывод вынесен во вьюшки. В ZF2 вообще красота. Можете полюбоваться: https://github.com/jhekasoft/j...

  • У меня есть знакомый программист, который очень бережно относится к разделению логики отображения и бизнес-логики. Он заботливо выносит тексты сообщений в отдельный message-файл. Тратит уйму времени на то, чтобы правильно назвать метод или переменную. При этом день за днем просерает дедлайн.
    А еще, из рассказа Умпутуна, есть такой программист, который писал код по офигенно правильному кошерному алгоритму: сначала писал тесты, а потом саму реализацию. Результат тот же, на простейшую задачу он тратил огромное количество времени.
    Так что не пугайтесь HTML-кода в php-файле. Главное результат. Ну это мое мнение такое.

  • jhekasoft
    Фанатизм не нужен. Но HTML-код целой формы в строке PHP это слишком говнокодно :)
    P.S. Умпутун и Бобук с «Радио-Т» рулят.



  • Иван
    Андрей, благодарю за очередной интересный урок!
    Не могли бы вы ответить на ряд вопросов, для изучающих РНР:
    1. В функции "m_add_new_user_temp" данные из массива $_GET сначала передаются в переменные ($user_name, $user_email), а потом уже в массив $vals[], для чего это сделано (если для того, чтобы было проще понимать код, тогда вопросов снимаю)? Не проще ли сразу же данные из массива $_GET передать в массив $vals[] без объявления дополнительных переменных?
    2. Правильно ли я понимаю, что после успешной регистрации пользователя, данные из промежуточной таблицы "m_reg_temp" не удаляются?
    3. Правильно ли я понимаю, что каких-либо ограничений для имени пользователя не существует, за исключением его длинны и уникальности? Не вызовет ли это конфликта при переносе данных в стандартную таблицу регистрации WP?
    P.S. Для того, чтобы было удобнее смотреть видео урок, можно сначала скачать код плагина, а потом одновременно смотреть запись и код, тогда проблем с размером шрифтов и качеством видео не возникает

  • Спасибо за интересный и грамотный вопрос.
    1. Из массива GET я передал данные в промежуточные переменные для большей наглядности. Я страдаю тем, что всегда делаю не как короче, а как понятнее.
    2. Действительно, код видеоурока не удаляет данные из промежуточной таблицы. Естественно они должны удаляться, для этого в таблицу есть поле ctime.
    Тут еще вот какой момент. Можно сразу после успешной валидации удалить соответствующую запись из промежуточной таблицы. Но, как мне кажется, делать этого нельзя. Ведь если посетитель повторно перейдет по валидационной ссылке, то он увидит сообщение о неверном валидацинном коде. А если запись хранить в течение месяца, то повторный переход выдаст ошибку с текстом "вы уже активировали свой аккаунт".
    3. Вот тут промашка в моей валидации. Необходимо регулярное выражение, регламентирующее правила для user_name. Цифры и буквы, начинать с буквы, думаю это то что нужно в данном случае.

  • mixumka
    "3. Вот тут промашка в моей валидации. Необходимо регулярное выражение,
    регламентирующее правила для user_name. Цифры и буквы, начинать с буквы,
    думаю это то что нужно в данном случае."
    А как зто исправить?

  • Юрий
    Спасибо за видеоурок.
    подскажите, где взять ссылку для подтверждения регистрации пользователя. Эта ссылка высылается в письме на емейл пользователя.
    Ссылка, которая по умолчанию в плагине - не работает.
    И
    еще один нюанс, если вылетает сообщение, что в строке 116 в файле плагина ошибка типа -
    не найдена функция username_exists() (что у меня произошло), то нужно
    будет подключить файл registration.php
    просто добавить в код первой строкой в файле плагина
    require_once(ABSPATH . WPINC . '/registration.php');

  • Чего-то я вопроса не понял. Смотрите видеоурок, на 12 минуте рассказывается как сформировать сообщение с валидационной ссылкой. Валидационную ссылку я сам подготавливаю для каждого пользователя следующим образом.
    Генерирую случайный код и записываю его в таблицу для данного пользователя. В этой же таблице хранится логин и пароль нового пользователя.
    Далее я дожидаюсь перехода по ссылке, которая будет содержать в массиве $_GET поле emailcode (или как-то так). Если данное поле в массиве $_GET обнаружено, то считать, что пользователь перешел по валидационной ссылке. В БД ищется строка, содержащая соответствующий проверочный код. Если строка найдена, то пользователь регистрируется в штатными методом WordPress.
    (Изменено автором 2 месяцев назад)

  • Юрий
    по умолчанию ссылка генерируется в плагине и имеет следующий вид: http://wordpress2.loc/?morkovin_code=$random_code
    т.е. когда пользователь по ней кликает, то браузер сообщает, что такой страницы не существует.
    Поэтому я заменил wordpress2.loc на адрес своего сайта, может я не правильно поступил?
    username_exists() — стандартная функция- так и есть, но она у меня почему-то не была подключена.
    (Изменено автором 2 месяцев назад)

  • Все правильно, нужно заменить wordpress2 на адрес своего сайта.

  • По поводу несуществующего метода username_exists(). Это очень странно, т.к. username_exists() — стандартная функция WordPress (http://codex.wordpress.org/Fun.... Почему она у Вас не существует, а у меня существует?

Комментариев нет:

Отправить комментарий