
Персонал сайта

Сообщений: 206
Зарегистрирован: 22.06.2011 15:00
|
Этот вопрос интересует многих, поскольку в один прекрасный момент страницы регистрации и просмотра профиля сменили облик с теплого лампового процедурного, на обьектно ориентированный, после чего неискушеннные пользователи стали массово производить кирпичи задавать вопросы, в попытках добиться прежней легкости изменения под себя этих файлов.
Итак, вот краткая инструкция, для желающих понять как оно теперь устроено и каким образом можно изменить страницы регистрации и редактирования профиля. Обратите внимание, что все описанное ниже касается актуальных версий PHP•FUSION.
Находим в недрах нашей системы файл includes\classes\UserFields.class.php, именно на него возложены все функции, которые отвечают на поставленные вопросы.
Файл содержит class UserFields, отвечающий за рендеринг форм регистрации и изменения профиля, а также за рендеринг полей профиля на странице пользователя.
Рассмотрим, из чего он состоит и с чем его едят. Все методы класса нам неинтересны, но на некоторые мы обратим внимание. Итак по порядку, начнем с методов используемых при регистрации и правке профиля.
Часть первая. Формы регистрации и редактирования профиля
public function displayInput — Вывод обертки всей формы регистрации и изменения профиля, инициализация всех полей ввода и js скриптов валидации.
Код$this->renderBasicInputFields();
$this->renderFields();
if ($this->displayValidation == 1) {
$this->renderValidation();
}
if ($this->displayTerms == 1) {
$this->renderTerms();
}
$this->renderButton();
Здесь вроде всё ясно и без слов.. логика такова:
- Сначала выводим базовые поля (renderBasicInputFields)
- Потом пользовательские user_fields (renderFields)
- Вывод выбранной в настройках сайта капчи (renderValidation)
- На странице регистрации, если включены правила сайта, то выводится чекбокс на подтверждение согласия с ними (renderTerms)
- Ну и естественно, вывод кнопки [зарегистрироваться | обновить профиль], куда ж без нее (renderButton)
Менять в этом методе класса нечего, разве что навесить на форму собственный js обработчик, ну или убрать/изменить стиль <table>, при желании сделав вывод полей не на основе строк таблицы, а на дивах, или например <dl> <dt> <dd> (что потребует небольшого косметического изменения всех user_fields).
********************
private function renderValidation — Вывод капчи.
В самом методе править особо нечего, но сюда подключается файл includes\captchas\выбранная капча\captcha_display.php с внешним (не сама картинка!) оформлением выбранной в настройках капчи. Для securimage Вы можете изменить в нем ширину <div>, в который обернут рисунок капчи, задать выравнивание и отступы, удалить кнопку прослушивания, разместить как душа пожелает кнопку обновления кода или сделать эту кнопку текстовой ссылкой [обновить].
Параметры же самого рисунка защитного кода, если конечно Вы не используете reCAPTCHA, изменяются в файлах includes\captchas\securimage\securimage_show.php или includes\captchas\securimage2\securimage_show.php, в зависимости от выбранной в настройках.
Основные настройки файла securimage_show.php:
Код$img->image_width = 216; // Ширина картинки
$img->image_height = 56; // Высота картинки
$img->code_lenght = 5; // Количество символов в коде
$img->text_color = new Securimage_Color("#666666"); // Цвет символов
$img->text_transparency_percentage = rand(10, 40); // Диапазон вариации прозрачности текста (100 - полностью прозрачный)
$img->num_lines = rand(5, 8); // Количество линий
$img->line_color = new Securimage_Color("#666666"); // Цвет линий
$img->draw_lines_over_text = true/false; // Рисовать линии поверх текста, или под ним
$img->ttf_file = "./ttf_fonts/".$ttf_fonts[rand(0, 8)].".ttf"; // Выбор случайного шрифта из массива $ttf_fonts = array();
$img->ttf_file = "./ttf_fonts/rogueo_hero_outline.ttf"; // Выбор одного любого .ttf шрифта
$img->perturbation = 0.6; // Коэффициент искажения символов
$img->text_angle_minimum = 10; // Угол минимального вращения символов
$img->text_angle_maximum = 20; // Угол максимального вращения символов
$img->use_wordlist = true/false; // Использовать или нет список слов
$img->charset = '0123456789'; // Набор используемых в капче символов (для примера я оставил только цифры)
Более подробную информацию смотрим на сайте securimage.
********************
private function renderTerms — Вывод правил сайта. Выводит локаль, со ссылочкой на страницу правил, чекбокс и js скрипт отключающий кнопку регистрации, пока этот чекбокс не отмечен.
Тут при желании можно заменить ссылку на правила, самими правилами. Добавив их вывод и оформив в <div> с фиксированной высотой и прокруткой.
Для этого перед <input type='checkbox' id='agreement' name='agreement' value='1' onclick='checkagreement()' /> вставляем код:
Код<div style='height:150px;overflow-y:auto;margin-bottom:10px;padding:10px 15px;background:#f7f7f7;border:1px solid #ededed'>
<strong>Правила пользования сайтом ".$settings['sitename']."</strong><hr />
".stripslashes($settings['license_agreement'])."<hr />
<span class='small'>Правила обновлены: ".ucfirst(showdate("longdate", $settings['license_lastupdate']))."</span>
</div>
и заменяем локаль ".$locale['u193'] ." на что то более подходящее, например «Подтверждаю что ознакомился с правилами сайта».
Поскольку мы используем здесь системные настройки $settings['sitename'], $settings['license_agreement'] и $settings['license_lastupdate'] — то добавляем в global переменную $settings.
global $locale, $settings;
Чтобы оценить результат смотрим на рис. 1 (не этот).

********************
private function basicInputField — Оформление вывода основных полей.
Тут можно подправить ширину левой ячейки width='150' на свою, изменить стандартную ширину текстовых инпутов style='width:200px;', или изменить значок обязательного поля $required = "<span style='color:#ff0000'>*</span>";, и даже вовсе избавиться от всех этих <td> </td>, перекроив всё на свой, гораздо более современный лад.
********************
private function renderBasicInputFields — Самая мякотка.. Вывод основных полей регистрации и редактирования профиля.
Здесь неплохой простор для фантазии, можно на свой вкус изменить порядок вывода основных полей, в форме регистрации и редактирования профиля. Поскольку по умолчанию, юзабилити здесь немножко отдохнуло.
Итак, для начала нам показывают заголовок «Пароли» , предлагают ввести пароль и подтвердить его, потом радуют заголовком «Информация об аккаунте» и наконец-то просят ввести «Имя пользователя» и «Email адрес». Редко где встречается такая последовательность, поэтому постараемся привести всё в более логический вид.
Берем метод renderBasicInputFields, и производим в нем рокировку базовых полей user_name, user_email, user_hide_email, user_password и прочих, по своему усмотрению, заодно подправив кое-какие мелочи.
Мой выбор прост и лаконичен, начинающие могут использовать как готовое решение:
Код// Вывод основных полей регистрации и редактирования профиля
private function renderBasicInputFields() {
global $locale;
// Ввод логина
$this->html .= (iADMIN || $this->_userNameChange ? $this->basicInputField("user_name", $locale['u127'], "30", $locale['u122']) : "");
// Ввод email
$this->html .= $this->basicInputField("user_email", $locale['u128'], "100", $locale['u126']);
// При регистрации незачем напрягать пользователя радиокнопками скрытия e-mail
// Это можно сделать и на странице правки профиля
if (preg_match("#edit_profile.php#i", FUSION_SELF)) {
$hide = isset($this->userData['user_hide_email']) ? $this->userData['user_hide_email'] : 1;
$hide = isset($_POST['user_hide_email']) && isnum($_POST['user_hide_email']) ? $_POST['user_hide_email'] : $hide;
$this->html .= "<tr>\n";
$this->html .= "<td class='tbl'>".$locale['u051']."</td>\n<td class='tbl'>";
$this->html .= "<label><input type='radio' name='user_hide_email' value='1'".($hide == 1 ? " checked='checked'" : "")." />".$locale['u053']."</label>\n";
$this->html .= "<label><input type='radio' name='user_hide_email' value='0'".($hide == 0 ? " checked='checked'" : "")." />".$locale['u052']."</label>";
$this->html .= "</td>\n</tr>\n";
// На странице регистрации выводим скрытое поле, в котором отключаем отображение e-mail
} else {
$this->html .= "<tr>\n<td colspan='2' style='margin:0;padding:0;'>";
$this->html .= "<input type='hidden' name='user_hide_email' value='1' /></td>\n";
$this->html .= "</tr>\n";
}
// Пароль
$passRequired = $this->skipCurrentPass ? $locale['u136'] : "";
$passRequired = $this->isAdminPanel ? "" : $passRequired;
// Убираем при регистрации заголовки категорий
if (preg_match("#edit_profile.php#i", FUSION_SELF)) {
$this->html .= "<tr>\n<td colspan='2' class='profile_category_name'>".$locale['u132']."</td>\n</tr>\n";
}
if (!$this->skipCurrentPass) {
$this->html .= $this->basicInputField("user_password", $locale['u133'], "64", "", "password", false, "user_password");
}
$this->html .= $this->basicInputField("user_new_password", ($this -> registration == TRUE ? $locale['u133'] : $locale['u134']), "64", $passRequired, "password", false, "user_password");
$this->html .= $this->basicInputField("user_new_password2", $locale['u135'], "64", $passRequired, "password", false, "user_password");
$this->html .= "<tr>\n<td class='tbl'></td>\n<td class='tbl'><span class='small2'>".$locale['u147']."</span></td>\n</tr>\n";
// Пароль администратора
if ($this->showAdminPass && iADMIN) {
$this->html .= "<tr>\n<td colspan='2' class='profile_category_name'>".$locale['u130']."</td></tr>\n";
if ($this->userData['user_admin_password']) {
$this->html .= $this->basicInputField("user_admin_password", $locale['u131'], "64", "", "password", false, "user_admin_password");
}
$this->html .= $this->basicInputField("user_new_admin_password", ($this -> userData['user_admin_password'] ? $locale['u144'] : $locale['u131']), "64", "", "password", false, "user_admin_password");
$this->html .= $this->basicInputField("user_new_admin_password2", $locale['u145'], "64", "", "password", false, "user_admin_password");
//$this->html .= "<tr>\n<td class='tbl'></td>\n<td class='tbl'><span class='small2'>".$locale['u147']."</span></td>\n</tr>\n";
}
// Убираем при регистрации заголовки категорий
if (preg_match("#edit_profile.php#i", FUSION_SELF)) {
// Информация об аккаунте
$this->html .= "<tr>\n<td colspan='2' class='profile_category_name'>".$locale['u129']."</td></tr>\n";
}
// Аватар
if ($this->showAvatarInput) {
$this->renderAvatarInput();
}
}
Результат можно увидеть на на рис. 2

В приведенном мной примере есть один момент, на который хотелось бы обратить внимание.
Код// На странице регистрации выводим скрытое поле, в котором отключаем отображение e-mail
} else {
$this->html .= "<tr>\n<td colspan='2' style='margin:0;padding:0;'>";
$this->html .= "<input type='hidden' name='user_hide_email' value='1' /></td>\n";
$this->html .= "</tr>\n";
}
Поскольку мы здесь удалили при регистрации кнопки скрытия e-mail, в этом фрагменте мы добавляем в форму скрытое поле, в котором этот параметр у регистрирующегося пользователи будет включен (e-mail скрыт).
Можно сделать проще и избавиться эт этого else, но тогда придется изменить в файле includes/classes/UserFieldsInput.class.php метод private function _setEmptyFields, отвечающий за незаполненные поля, изменив в нем всего один символ:
$this->_userHideEmail = isset($_POST['user_hide_email']) && $_POST['user_hide_email'] == 1 ? 1 : 0;
на
$this->_userHideEmail = isset($_POST['user_hide_email']) && $_POST['user_hide_email'] == 1 ? 1 : 1;
и e-mail пользователя будет всегда скрыт, пока он не изменит этот параметр в настройках своего профиля.
********************
private function renderAvatarInput — Выбор аватара.
Все просто. Вывод поля выбора изображения или отображение загруженного аватара и чекбокса для удаления. Если не нравится расположение элементов — можно подправить.
********************
private function renderButton — Вывод кнопки [регистрация | обновление профиля]. Комментарии излишни.
********************
private function getErrorClass — Задает стиль для ячейки, при валидации которой произошла ошибка.
CSS класс tbl-error, позволяет наравне с массивом ошибок в уведомлении, визуально отметить поля которые заполнены с ошибкой:
Код/* Ошибочные поля форм */
.tbl-error {color: #;}
.tbl-error .textbox {color: #; border: #;}
.tbl-error .textbox:focus {color: #; border: #;}
Один из возможных примеров использования класса tbl-error смотрим на рис. 3

********************
Теперь плавно переходим ко второй части. Методы отвечающие за вывод базовых полей пользователя и user_fields на странице просмотра профиля.
Часть вторая. Просмотр профиля пользователя
public function displayOutput — Построение структуры вывода профиля (по аналогии с public function displayInput)
Код$this->renderBasicOutputFields();
$this->renderFields();
if (iADMIN && checkrights("M")) {
$this->renderIPOutput();
}
if ($this->userData['user_groups']) {
$this->renderUserGroups();
}
if ($this->showAdminOptions && iADMIN && checkrights("M") && $this->userData['user_id'] != $userdata['user_id'] && $this->userData['user_level'] < 102) {
$this->renderAdminOptions();
}
Изначальная логика такова:
- Сначала выводим базовые поля (renderBasicOutputFields)
- Потом пользовательские user_fields (renderFields)
- Показываем админу IP пользователя (renderIPOutput)
- Выводим группы, в которых пользователь состоит (renderUserGroups)
- Показываем админу магические действия по отношению к пользователю, с
блэкджеком банхаммером и прочими прелестями (renderAdminOptions)
********************
А теперь обо всем этом поподробнее.
private function basicOutputField — Оформление вывода основных полей.
Кодprivate function basicOutputField($name, $value, $class, $rowspan = 0) {
global $locale;
$returnHTML = "<tr>\n";
// Аватар
if ($rowspan > 0) {
$returnHTML .= "<td rowspan='".$rowspan."' valign='top' class='tbl profile_user_avatar' width='1%'><!--profile_user_avatar-->";
$returnHTML .= "<img src='".IMAGES."avatars/".$this->userData['user_avatar']."' class='avatar' alt='".$locale['u062']."' title='".$locale['u062']."' />";
$returnHTML .= "</td>\n";
}
// Левая колонка основных полей
$returnHTML .= "<td class='tbl1'>".$name."</td>\n";
// Правая колонка основных полей
$returnHTML .= "<td align='right' class='".$class." tbl1'><!--".$class."-->".$value."</td>\n";
$returnHTML .= "</tr>\n";
return $returnHTML;
}
********************
private function renderBasicOutputFields — Самая верхняя часть просмотра профиля. Таблица, где слева находится аватар, а справа основные поля (имя пользователя, уровень пользователя, дата регистрации и последнее посещение). Смотрим комментарии, вникаем, изменяем.
Кодprivate function renderBasicOutputFields() {
global $locale, $userdata, $aidlink;
$rowspan = 4;
$this->html .= "<table cellpadding='0' cellspacing='1' width='400' class='profile tbl-border center'>\n";
// Уровень пользователя
$returnFields = $this->basicOutputField($locale['u063'], getuserlevel($this->userData['user_level']), "profile_user_level");
// E-mail (показываем только админу, или всем, с позволения пользователя)
if (iADMIN || $this->userData['user_hide_email'] == 0) {
$rowspan = $rowspan + 1;
$returnFields .= $this->basicOutputField($locale['u064'], hide_email($this->userData['user_email']), "profile_user_email");
}
// Дата регистрации
$returnFields .= $this->basicOutputField($locale['u066'], showdate("longdate", $this->userData['user_joined']), "profile_user_joined");
// Последнее посещение
$lastVisit = $this->userData['user_lastvisit'] ? showdate("longdate", $this->userData['user_lastvisit']) : $locale['u042'];
$returnFields .= $this->basicOutputField($locale['u067'], $lastVisit, "profile_user_visit");
// Если нет аватара, показываем дефолтный
if ($this->userData['user_avatar'] == "" || !file_exists(IMAGES."avatars/".$this->userData['user_avatar'])) {
$this->userData['user_avatar'] = "noavatar100.png";
}
// Имя пользователя
$this->html .= $this->basicOutputField($locale['u068'], $this->userData['user_name'], "profile_user_name", $rowspan);
$this->html .= $returnFields;
// Строка написать сообщение, посмотреть лог
if (iMEMBER && $userdata['user_id'] != $this->userData['user_id']) {
$this->html .= "<tr><td colspan='3' class='user_profile_opts center tbl2'>";
// Кнопка [написать сообщение]
$this->html .= "<a href='".BASEDIR."messages.php?msg_send=".$this->userData['user_id']."' title='".$locale['u043']."'>".$locale['u043']."</a>\n";
// Просмотр лога пользователя (для администраторов)
if (iADMIN && checkrights("M") && $this->userData['user_level'] != "103" && $this->userData['user_id'] != "1") {
$this->html .= " - <a href='".ADMIN."members.php".$aidlink."&step=log&user_id=".$this->userData['user_id']."'>".$locale['u054']."</a>";
}
$this->html .= "<!--user_profile_opts-->";
$this->html .= "</td>\n</tr>\n";
}
$this->html .= "</table>\n";
// Информация о причине бана или заморозки (для администраторов)
if (iADMIN && $this->userData['user_status'] > 0) {
$this->html .= "<div style='margin:5px'></div>\n";
$this->html .= "<table cellpadding='0' cellspacing='1' width='400' class='profile tbl-border center'>\n<tr>\n";
$this->html .= "<td colspan='2' class='tbl2'><strong>".$locale['u055']."</strong> ".getuserstatus($this->userData['user_status'])."</td>\n";
$this->html .= "</tr>\n";
$this->html .= $this->basicOutputField($locale['u056'], $this->userData['suspend_reason'], "profile_user_reason");
$this->html .= "</table>\n";
}
}
Можем менять здесь стили, ширину, добавлять, удалять или переносить элементы и кнопки. Не забываем при необходимости дописывать новые используемые данные в global.
********************
private function renderIPOutput — Администраторская информация. Вывод IP пользователя.
********************
private function renderUserGroups — Вывод групп, в которых состоит пользователь.
********************
private function renderAdminOptions — Опции администратора
********************
private function renderFields — Рендеринг пользовательских полей (user_fields).
Используется как на страницах ввода данных, так и на странице просмотра профиля. Именно этот метод выводит все категории пользовательских полей, и сами принадлежащие им user_fields поля, с учетом сортировки в админке (administration/user_field_cats.php и administration/user_fields.php), а на странице регистрации отмечает их звездочкой * если поле настроено как обязательное.
Здесь тоже есть простор для экспериментов. Можно изменить вывод заголовков категорий, вообще их удалить, при желании переделать всё на дивы™, или хотя бы подправить под себя некоторые CSS классы, и ширину таблицы вывода на странице профиля, хотя это можно сделать и просто через CSS, запомнив, какой класс отвечает за таблицы категорий полей:
$this->html .= "<table cellpadding='0' cellspacing='1' width='400' class='profile_category tbl-border center'>\n";
********************
Лирическое отступление, или короткий ликбез о user_fields для начинающих:
Каждое из существующих пользовательских полей includes\user_fields\, например user_icq_include.php состоит из трех основных методов:
- input — Отображение поля при вводе данных (регистрация или редактирование профиля)
- display — Вывод введенных данных на странице просмотра профиля
- validate_insert || validate_update — Валидация данных, при записи в БД.
Для полей, кроме сортировки и принадлежности к какой-либо категории, также доступны три пункта настройки:
- Требуется — Поле становится обязательным при заполнении (required).
- Регистрация — Поле выводится при регистрации
- Журнал — Для этого поля в отдельной таблице БД будут сохраняться все изменения, производимые пользователем. Что бывает полезно для отслеживания некоторых нехороших тенденций
Дополнительные пользовательские поля для вашего сайта вы можете найти здесь. Поскольку в ранних версиях 7-й ветки PHP-Fusion сменилось API пользовательских полей — во избежание проблем с совместимостью, выбирайте только актуальные для вашей версии движка аддоны.
Chief присоединено следующее:изображения:
Изменил(а) Chief, 18.10.2013 13:37
У богатых людей — большая библиотека. У бедных людей — большой телевизор.
|