AdminGroups, Csrf, Validator, ...

This commit is contained in:
Visman 2017-04-09 21:32:49 +07:00
parent 4efdcbdfde
commit 44bee23a23
20 changed files with 1419 additions and 122 deletions

View file

@ -96,6 +96,12 @@ class Routing
// только админ
if ($user->isAdmin) {
$r->add('GET', '/admin/statistics/info', 'AdminStatistics:info', 'AdminInfo');
$r->add('GET', '/admin/groups', 'AdminGroups:view', 'AdminGroups');
$r->add('POST', '/admin/groups/new[/{base:[1-9]\d*}]', 'AdminGroups:newPost', 'AdminGroupsNew');
$r->add('POST', '/admin/groups/default', 'AdminGroups:defaultPost', 'AdminGroupsDefault');
$r->add('GET', '/admin/groups/edit/{id:[1-9]\d*}', 'AdminGroups:edit', 'AdminGroupsEdit');
$r->add('POST', '/admin/groups/edit/{id:[1-9]\d*}', 'AdminGroups:editPost');
$r->add('GET', '/admin/groups/delete/{id:[1-9]\d*}', 'AdminGroups:delete', 'AdminGroupsDelete');
}
$uri = $_SERVER['REQUEST_URI'];

View file

@ -37,9 +37,13 @@ class Csrf
public function create($marker, array $args = [], $time = null)
{
unset($args['token'], $args['#']);
$data = $marker . '|' . json_encode($args);
ksort($args);
$marker .= '|';
foreach ($args as $key => $value) {
$marker .= $key . '|' . (string) $value . '|';
}
$time = $time ?: time();
return $this->secury->hmac($data, $time . $this->key) . 'f' . $time;
return $this->secury->hmac($marker, $time . $this->key) . 'f' . $time;
}
/**

View file

@ -90,6 +90,7 @@ class Validator
'max' => [$this, 'vMax'],
'min' => [$this, 'vMin'],
'numeric' => [$this, 'vNumeric'],
'not_in' => [$this, 'vNotIn'],
'password' => [$this, 'vPassword'],
'referer' => [$this, 'vReferer'],
'regex' => [$this, 'vRegex'],
@ -354,7 +355,7 @@ class Validator
protected function vRequiredWith($v, $value, $attr)
{
foreach (explode(',', $attr) as $field) {
if (null !== $this->__get($field) {
if (null !== $this->__get($field)) {
return $this->vRequired($v, $value);
}
}
@ -534,7 +535,16 @@ class Validator
if (null === $value || in_array($value, explode(',', $attr))) {
return [$value, false];
} else {
return [null, 'The :alias contains an invalid value'];
return [$value, 'The :alias contains an invalid value'];
}
}
protected function vNotIn($v, $value, $attr)
{
if (null === $value || ! in_array($value, explode(',', $attr))) {
return [$value, false];
} else {
return [$value, 'The :alias contains an invalid value'];
}
}
}

View file

@ -29,11 +29,11 @@ class View extends Dirk
*/
protected function compileTransformations($value)
{
if (strpos($value, '<!--inline-->') === false) {
if (strpos($value, '<!-- inline -->') === false) {
return $value;
}
return preg_replace_callback(
'%<!--inline-->([^<]*(?:<(?!!--endinline-->)[^<]*)*+)(?:<!--endinline-->)?%',
'%<!-- inline -->([^<]*(?:<(?!!-- endinline -->)[^<]*)*+)(?:<!-- endinline -->)?%',
function ($matches) {
return preg_replace('%\h*\R\s*%', '', $matches[1]);
},

View file

@ -25,6 +25,12 @@ abstract class Admin extends Page
*/
protected $onlinePos = 'admin';
/**
* Переменная для meta name="robots"
* @var string
*/
protected $robots = 'noindex, nofollow';
/**
* Конструктор
* @param Container $container
@ -87,7 +93,7 @@ abstract class Admin extends Page
'permissions' => ['admin_permissions.php', __('Permissions')],
'categories' => ['admin_categories.php', __('Categories')],
'forums' => ['admin_forums.php', __('Forums')],
'groups' => ['admin_groups.php', __('User groups')],
'groups' => [$r->link('AdminGroups'), __('User groups')],
'censoring' => ['admin_censoring.php', __('Censoring')],
'maintenance' => ['admin_maintenance.php', __('Maintenance')]
];

View file

@ -0,0 +1,575 @@
<?php
namespace ForkBB\Models\Pages\Admin;
use ForkBB\Core\Container;
use ForkBB\Core\Validator;
class Groups extends Admin
{
/**
* Имя шаблона
* @var string
*/
protected $nameTpl = 'admin/groups';
/**
* Указатель на активный пункт навигации админки
* @var string
*/
protected $adminIndex = 'groups';
/**
* Массив групп
* @var array
*/
protected $groups;
/**
* Список групп доступных как основа для новой
* @var array
*/
protected $grBase = [];
/**
* Список групп доступных для группы по умолчанию
* @var array
*/
protected $grDefault = [];
/**
* Список групп доступных для удаления
* @var array
*/
protected $grDelete = [];
/**
* Конструктор
* @param Container $container
*/
public function __construct(Container $container)
{
parent::__construct($container);
$this->getGroup();
$forBase = [$this->c->GROUP_UNVERIFIED, $this->c->GROUP_ADMIN, $this->c->GROUP_GUEST];
$forDelete = [$this->c->GROUP_UNVERIFIED, $this->c->GROUP_ADMIN, $this->c->GROUP_MOD, $this->c->GROUP_GUEST, $this->c->GROUP_MEMBER];
foreach ($this->groups as $key => $cur) {
if (! in_array($key, $forBase)) {
$this->grBase[$key] = true;
if ($cur['g_moderator'] == 0) {
$this->grDefault[$key] = true;
}
if (! in_array($key, $forDelete)) {
$this->grDelete[$key] = true;
}
}
}
}
/**
* Создает массив групп
*/
protected function getGroup()
{
if (empty($this->groups)) {
$this->groups = [];
$stmt = $this->c->DB->query('SELECT * FROM ::groups ORDER BY g_id');
while ($cur = $stmt->fetch()) {
$this->groups[$cur['g_id']] = $cur;
}
}
}
/**
* Подготавливает данные для шаблона
* @return Page
*/
public function view()
{
$groupsList = [];
$groupsNew = [];
$groupsDefault = [];
foreach ($this->groups as $key => $cur) {
$groupsList[] = [
$this->c->Router->link('AdminGroupsEdit', ['id' => $key]),
$cur['g_title'],
isset($this->grDelete[$key])
? $this->c->Router->link('AdminGroupsDelete', ['id' => $key])
: null,
];
if (isset($this->grBase[$key])) {
$groupsNew[] = [$key, $cur['g_title']];
}
if (isset($this->grDefault[$key])) {
$groupsDefault[] = [$key, $cur['g_title']];
}
}
$this->c->Lang->load('admin_groups');
$this->data = [
'formActionNew' => $this->c->Router->link('AdminGroupsNew'),
'formTokenNew' => $this->c->Csrf->create('AdminGroupsNew'),
'formActionDefault' => $this->c->Router->link('AdminGroupsDefault'),
'formTokenDefault' => $this->c->Csrf->create('AdminGroupsDefault'),
'defaultGroup' => $this->config['o_default_user_group'],
'groupsNew' => $groupsNew,
'groupsDefault' => $groupsDefault,
'groupsList' => $groupsList,
'tabindex' => 0,
];
return $this;
}
/**
* Устанавливает группу по умолчанию
* @return Page
*/
public function defaultPost()
{
$this->c->Lang->load('admin_groups');
$v = $this->c->Validator->setRules([
'token' => 'token:AdminGroupsDefault',
'defaultgroup' => 'required|integer|in:' . implode(',', array_keys($this->grDefault)),
]);
if (! $v->validation($_POST)) {
$this->iswev = $v->getErrors();
return $this->view();
}
$this->c->DB->exec('UPDATE ::config SET conf_value=?s:id WHERE conf_name=\'o_default_user_group\'', [':id' => $v->defaultgroup]);
$this->c->{'config update'};
return $this->c->Redirect->setPage('AdminGroups')->setMessage(__('Default group redirect'));
}
/**
* Подготавливает данные для создание группы
* Создает новую группу
* @param array $args
* @return Page
*/
public function newPost(array $args)
{
$this->c->Lang->load('admin_groups');
if (empty($args['base'])) {
$v = $this->c->Validator->setRules([
'token' => 'token:AdminGroupsNew',
'basegroup' => ['required|integer|in:' . implode(',', array_keys($this->grBase)), __('New group label')]
]);
if (! $v->validation($_POST)) {
$this->iswev = $v->getErrors();
return $this->view();
} else {
return $this->edit(['id' => $v->basegroup, '_new' => true]);
}
} else {
return $this->editPost(['id' => $args['base'], '_new' => true]);
}
}
/**
* Подготавливает данные для шаблона редактирования группы
* @param array $args
* @return Page
*/
public function edit(array $args)
{
$groups = $this->groups;
if (isset($args['_data'])) {
$groups[$args['id']] = $args['_data'];
} elseif (! isset($groups[$args['id']])) {
return $this->c->Message->message('Bad request');
}
if (isset($args['_new'])) {
$id = -1;
$marker = 'AdminGroupsNew';
$vars = ['base' => $args['id']];
if (! isset($args['_data'])) {
unset($groups[$args['id']]['g_title']);
}
} else {
$id = (int) $args['id'];
$marker = 'AdminGroupsEdit';
$vars = ['id' => $id];
}
$this->c->Lang->load('admin_groups');
$this->data = [
'formAction' => $this->c->Router->link($marker, $vars),
'formToken' => $this->c->Csrf->create($marker, $vars),
'form' => $this->viewForm($id, $groups[$args['id']]),
'warn' => empty($groups[$args['id']]['g_moderator']) ? null : __('Moderator info'),
'tabindex' => 0,
];
return $this;
}
/**
* Запись данных по новой/измененной группе
* @param array $args
* @return Page
*/
public function editPost(array $args)
{
$next = $this->c->GROUP_ADMIN . ',' . $this->c->GROUP_GUEST;
if (isset($args['_new'])) {
$id = -1;
$marker = 'AdminGroupsNew';
$vars = ['base' => $args['id']];
} else {
$id = (int) $args['id'];
$marker = 'AdminGroupsEdit';
$vars = ['id' => $id];
$next .= ',' . $id;
}
$reserve = [];
foreach ($this->groups as $key => $cur) {
if ($key != $id) {
$reserve[] = $cur['g_title'];
}
}
$this->c->Lang->load('admin_groups');
$v = $this->c->Validator->setRules([
'token' => 'token:' . $marker,
'g_title' => 'required|string:trim|max:50|not_in:' . implode(',', $reserve),
'g_user_title' => 'string:trim|max:50',
'g_promote_next_group' => 'integer|min:0|not_in:' . $next,
'g_promote_min_posts' => 'integer|min:0|max:9999999999',
'g_moderator' => 'integer|in:0,1',
'g_mod_edit_users' => 'integer|in:0,1',
'g_mod_rename_users' => 'integer|in:0,1',
'g_mod_change_passwords' => 'integer|in:0,1',
'g_mod_promote_users' => 'integer|in:0,1',
'g_mod_ban_users' => 'integer|in:0,1',
'g_read_board' => 'integer|in:0,1',
'g_view_users' => 'integer|in:0,1',
'g_post_replies' => 'integer|in:0,1',
'g_post_topics' => 'integer|in:0,1',
'g_edit_posts' => 'integer|in:0,1',
'g_delete_posts' => 'integer|in:0,1',
'g_delete_topics' => 'integer|in:0,1',
'g_set_title' => 'integer|in:0,1',
'g_post_links' => 'integer|in:0,1',
'g_search' => 'integer|in:0,1',
'g_search_users' => 'integer|in:0,1',
'g_send_email' => 'integer|in:0,1',
'g_post_flood' => 'integer|min:0|max:999999',
'g_search_flood' => 'integer|min:0|max:999999',
'g_email_flood' => 'integer|min:0|max:999999',
'g_report_flood' => 'integer|min:0|max:999999',
])->setArguments([
'token' => $vars,
]);
if (! $v->validation($_POST)) {
$this->iswev = $v->getErrors();
$args['_data'] = $v->getData();
return $this->edit($args);
}
$data = $v->getData();
if (empty($data['g_moderator'])) {
$data['g_mod_edit_users'] = 0;
$data['g_mod_rename_users'] = 0;
$data['g_mod_change_passwords'] = 0;
$data['g_mod_promote_users'] = 0;
$data['g_mod_ban_users'] = 0;
}
if ($data['g_promote_next_group'] * $data['g_promote_min_posts'] == 0) {
$data['g_promote_next_group'] = 0;
$data['g_promote_min_posts'] = 0;
}
$fields = [];
$sets = [];
$vars = [];
foreach($data as $key => $value) {
if (substr($key, 0, 2) !== 'g_' || $value === null) {
continue;
} elseif ($key === 'g_user_title' && ! isset($value{0})) {
$value = null;
}
if ($id === -1) {
$fields[] = $key;
$sets[] = is_int($value) ? '?i' : '?s';
$vars[] = $value;
} else {
if ($id === $this->c->GROUP_ADMIN
&& ! in_array($key, ['g_title', 'g_user_title'])
) {
continue;
}
$sets[] = $key . '=' . (is_int($value) ? '?i' : '?s');
$vars[] = $value;
}
}
if ($id === -1) {
$this->c->DB->exec('INSERT INTO ::groups (' . implode(', ', $fields) . ') VALUES(' . implode(', ', $sets) . ')', $vars);
$newId = $this->c->DB->lastInsertId();
$this->c->DB->exec('INSERT INTO ::forum_perms (group_id, forum_id, read_forum, post_replies, post_topics) SELECT ?i:new, forum_id, read_forum, post_replies, post_topics FROM ::forum_perms WHERE group_id=?i:old', [':new' => $newId, ':old' => $args['id']]);
} else {
$vars[] = $id;
$this->c->DB->exec('UPDATE ::groups SET ' . implode(', ', $sets) . ' WHERE g_id=?i', $vars);
if ($data['g_promote_next_group']) {
$vars = [':next' => $data['g_promote_next_group'], ':id' => $id, ':posts' => $data['g_promote_min_posts']];
$this->c->DB->exec('UPDATE ::users SET group_id=?i:next WHERE group_id=?i:id AND num_posts>=?i:posts', $vars);
}
}
$this->c->Cache->delete('forums_mark');
return $this->c->Redirect
->setPage('AdminGroups')
->setMessage($id === -1 ? __('Group added redirect') : __('Group edited redirect'));
}
/**
* Формирует данные для формы редактирования группы
* @param int $id
* @param array $data
* @return array
*/
protected function viewForm($id, array $data)
{
$this->nameTpl = 'admin/group';
$form = [
'g_title' => [
'type' => 'text',
'maxlength' => 50,
'value' => isset($data['g_title']) ? $data['g_title'] : '',
'title' => __('Group title label'),
'required' => true,
],
'g_user_title' => [
'type' => 'text',
'maxlength' => 50,
'value' => isset($data['g_user_title']) ? $data['g_user_title'] : '',
'title' => __('User title label'),
'info' => __('User title help', $id == $this->c->GROUP_GUEST ? __('Guest') : __('Member')),
],
];
if ($id === $this->c->GROUP_UNVERIFIED || $id === $this->c->GROUP_ADMIN) {
return $form;
}
if ($id !== $this->c->GROUP_GUEST) {
$options = [0 => __('Disable promotion')];
foreach ($this->groups as $group) {
if ($group['g_id'] == $id || empty($this->grBase[$group['g_id']])) {
continue;
}
$options[$group['g_id']] = $group['g_title'];
}
$form['g_promote_next_group'] = [
'type' => 'select',
'options' => $options,
'value' => isset($data['g_promote_next_group']) ? $data['g_promote_next_group'] : 0,
'title' => __('Promote users label'),
'info' => __('Promote users help', __('Disable promotion')),
];
$form['g_promote_min_posts'] = [
'type' => 'number',
'min' => 0,
'max' => 9999999999,
'value' => isset($data['g_promote_min_posts']) ? $data['g_promote_min_posts'] : 0,
'title' => __('Number for promotion label'),
'info' => __('Number for promotion help'),
];
}
$y = __('Yes');
$n = __('No');
if ($id !== $this->c->GROUP_GUEST && $id != $this->config['o_default_user_group']) {
$form['g_moderator'] = [
'type' => 'radio',
'value' => isset($data['g_moderator']) ? $data['g_moderator'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('Mod privileges label'),
'info' => __('Mod privileges help'),
];
$form['g_mod_edit_users'] = [
'type' => 'radio',
'value' => isset($data['g_mod_edit_users']) ? $data['g_mod_edit_users'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('Edit profile label'),
'info' => __('Edit profile help'),
];
$form['g_mod_rename_users'] = [
'type' => 'radio',
'value' => isset($data['g_mod_rename_users']) ? $data['g_mod_rename_users'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('Rename users label'),
'info' => __('Rename users help'),
];
$form['g_mod_change_passwords'] = [
'type' => 'radio',
'value' => isset($data['g_mod_change_passwords']) ? $data['g_mod_change_passwords'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('Change passwords label'),
'info' => __('Change passwords help'),
];
$form['g_mod_promote_users'] = [
'type' => 'radio',
'value' => isset($data['g_mod_promote_users']) ? $data['g_mod_promote_users'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('Mod promote users label'),
'info' => __('Mod promote users help'),
];
$form['g_mod_ban_users'] = [
'type' => 'radio',
'value' => isset($data['g_mod_ban_users']) ? $data['g_mod_ban_users'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('Ban users label'),
'info' => __('Ban users help'),
];
}
$form['g_read_board'] = [
'type' => 'radio',
'value' => isset($data['g_read_board']) ? $data['g_read_board'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('Read board label'),
'info' => __('Read board help'),
];
$form['g_view_users'] = [
'type' => 'radio',
'value' => isset($data['g_view_users']) ? $data['g_view_users'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('View user info label'),
'info' => __('View user info help'),
];
$form['g_post_replies'] = [
'type' => 'radio',
'value' => isset($data['g_post_replies']) ? $data['g_post_replies'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('Post replies label'),
'info' => __('Post replies help'),
];
$form['g_post_topics'] = [
'type' => 'radio',
'value' => isset($data['g_post_topics']) ? $data['g_post_topics'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('Post topics label'),
'info' => __('Post topics help'),
];
if ($id !== $this->c->GROUP_GUEST) {
$form['g_edit_posts'] = [
'type' => 'radio',
'value' => isset($data['g_edit_posts']) ? $data['g_edit_posts'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('Edit posts label'),
'info' => __('Edit posts help'),
];
$form['g_delete_posts'] = [
'type' => 'radio',
'value' => isset($data['g_delete_posts']) ? $data['g_delete_posts'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('Delete posts label'),
'info' => __('Delete posts help'),
];
$form['g_delete_topics'] = [
'type' => 'radio',
'value' => isset($data['g_delete_topics']) ? $data['g_delete_topics'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('Delete topics label'),
'info' => __('Delete topics help'),
];
$form['g_set_title'] = [
'type' => 'radio',
'value' => isset($data['g_set_title']) ? $data['g_set_title'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('Set own title label'),
'info' => __('Set own title help'),
];
}
$form['g_post_links'] = [
'type' => 'radio',
'value' => isset($data['g_post_links']) ? $data['g_post_links'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('Post links label'),
'info' => __('Post links help'),
];
$form['g_search'] = [
'type' => 'radio',
'value' => isset($data['g_search']) ? $data['g_search'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('User search label'),
'info' => __('User search help'),
];
$form['g_search_users'] = [
'type' => 'radio',
'value' => isset($data['g_search_users']) ? $data['g_search_users'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('User list search label'),
'info' => __('User list search help'),
];
if ($id !== $this->c->GROUP_GUEST) {
$form['g_send_email'] = [
'type' => 'radio',
'value' => isset($data['g_send_email']) ? $data['g_send_email'] : 0,
'values' => [1 => $y, 0 => $n],
'title' => __('Send e-mails label'),
'info' => __('Send e-mails help'),
];
}
$form['g_post_flood'] = [
'type' => 'number',
'min' => 0,
'max' => 999999,
'value' => isset($data['g_post_flood']) ? $data['g_post_flood'] : 0,
'title' => __('Post flood label'),
'info' => __('Post flood help'),
];
$form['g_search_flood'] = [
'type' => 'number',
'min' => 0,
'max' => 999999,
'value' => isset($data['g_search_flood']) ? $data['g_search_flood'] : 0,
'title' => __('Search flood label'),
'info' => __('Search flood help'),
];
if ($id !== $this->c->GROUP_GUEST) {
$form['g_email_flood'] = [
'type' => 'number',
'min' => 0,
'max' => 999999,
'value' => isset($data['g_email_flood']) ? $data['g_email_flood'] : 0,
'title' => __('E-mail flood label'),
'info' => __('E-mail flood help'),
];
$form['g_report_flood'] = [
'type' => 'number',
'min' => 0,
'max' => 999999,
'value' => isset($data['g_report_flood']) ? $data['g_report_flood'] : 0,
'title' => __('Report flood label'),
'info' => __('Report flood help'),
];
}
return $form;
}
}

View file

@ -0,0 +1,265 @@
#
msgid ""
msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Project-Id-Version: ForkBB\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: ForkBB <mio.visman@yandex.ru>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: en\n"
msgid "Must enter title message"
msgstr "You must enter a group title."
msgid "Title already exists message"
msgstr "There is already a group with the title <strong>%s</strong>."
msgid "Default group redirect"
msgstr "Default group set. Redirecting …"
msgid "Cannot remove default message"
msgstr "The default group cannot be removed. In order to delete this group, you must first setup a different group as the default."
msgid "Group removed redirect"
msgstr "Group removed. Redirecting …"
msgid "Group added redirect"
msgstr "Group added. Redirecting …"
msgid "Group edited redirect"
msgstr "Group edited. Redirecting …"
msgid "Control of groups"
msgstr "Control of groups"
msgid "Add group subhead"
msgstr "Add new group"
msgid "New group label"
msgstr "Base new group on"
msgid "New group help"
msgstr "Select a user group from which the new group will inherit its permission settings. The next page will let you fine-tune its settings."
msgid "Default group subhead"
msgstr "Set default group"
msgid "Default group label"
msgstr "Default group"
msgid "Default group help"
msgstr "This is the default user group, e.g. the group users are placed in when they register. For security reasons, users can't be placed in either the moderator or administrator user groups by default."
msgid "Existing groups head"
msgstr "Existing groups"
msgid "Edit groups subhead"
msgstr "Edit/delete groups"
msgid "Edit groups info"
msgstr "The pre-defined groups Guests, Administrators, Moderators and Members cannot be removed. However, they can be edited. Please note that in some groups, some options are unavailable (e.g. the <em>edit posts</em> permission for guests). Administrators always have full permissions."
msgid "Edit link"
msgstr "Edit"
msgid "Delete link"
msgstr "Delete"
msgid "Group delete head"
msgstr "Group delete"
msgid "Confirm delete subhead"
msgstr "Confirm delete group"
msgid "Confirm delete info"
msgstr "Are you sure that you want to delete the group <strong>%s</strong>?"
msgid "Confirm delete warn"
msgstr "WARNING! After you deleted a group you cannot restore it."
msgid "Delete group head"
msgstr "Delete group"
msgid "Move users subhead"
msgstr "Move users currently in group"
msgid "Move users info"
msgstr "The group <strong>%s</strong> currently has <strong>%s</strong> members. Please select a group to which these members will be assigned upon deletion."
msgid "Move users label"
msgstr "Move users to"
msgid "Delete group"
msgstr "Delete group"
msgid "Group settings head"
msgstr "Group settings"
msgid "Group settings subhead"
msgstr "Setup group options and permissions"
msgid "Group settings info"
msgstr "Below options and permissions are the default permissions for the user group. These options apply if no forum specific permissions are in effect."
msgid "Group title label"
msgstr "Group title"
msgid "User title label"
msgstr "User title"
msgid "User title help"
msgstr "The rank users in this group have attained. Leave blank to use default title ("%s")."
msgid "Promote users label"
msgstr "Promote users"
msgid "Promote users help"
msgstr "You can promote users to a new group automatically if they reach a certain number of posts. Select "%s" to disable. For security reasons, you are not allowed to select an administrator group here. Also note that group changes for users affected by this setting will take effect <strong>immediately</strong>."
msgid "Number for promotion label"
msgstr "Number of messages for promotion"
msgid "Number for promotion help"
msgstr "Note that the amount of posts you enter is the total amount of posts of a user, not the amount of posts made as a member of this group."
msgid "Disable promotion"
msgstr "Disable promoting"
msgid "Mod privileges label"
msgstr "Allow users moderator privileges"
msgid "Mod privileges help"
msgstr "In order for a user in this group to have moderator abilities, he/she must be assigned to moderate one or more forums. This is done via the user administration page of the user's profile."
msgid "Edit profile label"
msgstr "Allow moderators to edit user profiles"
msgid "Edit profile help"
msgstr "If moderator privileges are enabled, allow users in this group to edit user profiles."
msgid "Rename users label"
msgstr "Allow moderators to rename users"
msgid "Rename users help"
msgstr "If moderator privileges are enabled, allow users in this group to rename users."
msgid "Change passwords label"
msgstr "Allow moderators to change passwords"
msgid "Change passwords help"
msgstr "If moderator privileges are enabled, allow users in this group to change user passwords."
msgid "Mod promote users label"
msgstr "Allow moderators to promote users"
msgid "Mod promote users help"
msgstr "If moderator privileges are enabled, allow users in this group to promote users."
msgid "Ban users label"
msgstr "Allow moderators to ban users"
msgid "Ban users help"
msgstr "If moderator privileges are enabled, allow users in this group to ban users."
msgid "Read board label"
msgstr "Read board"
msgid "Read board help"
msgstr "Allow users in this group to view the board. This setting applies to every aspect of the board and can therefore not be overridden by forum specific settings. If this is set to "No", users in this group will only be able to login/logout and register."
msgid "View user info label"
msgstr "View user information"
msgid "View user info help"
msgstr "Allow users to view the user list and user profiles."
msgid "Post replies label"
msgstr "Post replies"
msgid "Post replies help"
msgstr "Allow users in this group to post replies in topics."
msgid "Post topics label"
msgstr "Post topics"
msgid "Post topics help"
msgstr "Allow users in this group to post new topics."
msgid "Edit posts label"
msgstr "Edit posts"
msgid "Edit posts help"
msgstr "Allow users in this group to edit their own posts."
msgid "Delete posts label"
msgstr "Delete posts"
msgid "Delete posts help"
msgstr "Allow users in this group to delete their own posts."
msgid "Delete topics label"
msgstr "Delete topics"
msgid "Delete topics help"
msgstr "Allow users in this group to delete their own topics (including any replies)."
msgid "Post links label"
msgstr "Post links"
msgid "Post links help"
msgstr "Allow users in this group to include links in their posts. This setting also applies to signatures and the website field in users' profiles."
msgid "Set own title label"
msgstr "Set own user title"
msgid "Set own title help"
msgstr "Allow users in this group to set their own user title."
msgid "User search label"
msgstr "Use search"
msgid "User search help"
msgstr "Allow users in this group to use the search feature."
msgid "User list search label"
msgstr "Search user list"
msgid "User list search help"
msgstr "Allow users in this group to freetext search for users in the user list."
msgid "Send e-mails label"
msgstr "Send e-mails"
msgid "Send e-mails help"
msgstr "Allow users in this group to send e-mails to other users."
msgid "Post flood label"
msgstr "Post flood interval"
msgid "Post flood help"
msgstr "Number of seconds that users in this group have to wait between posts. Set to 0 to disable."
msgid "Search flood label"
msgstr "Search flood interval"
msgid "Search flood help"
msgstr "Number of seconds that users in this group have to wait between searches. Set to 0 to disable."
msgid "E-mail flood label"
msgstr "Email flood interval"
msgid "E-mail flood help"
msgstr "Number of seconds that users in this group have to wait between emails. Set to 0 to disable."
msgid "Report flood label"
msgstr "Report flood interval"
msgid "Report flood help"
msgstr "Number of seconds that users in this group have to wait between reports. Set to 0 to disable."
msgid "Moderator info"
msgstr "Please note that in order for a user in this group to have moderator abilities, he/she must be assigned to moderate one or more forums. This is done via the user administration page of the user's profile."

View file

@ -0,0 +1,265 @@
#
msgid ""
msgstr ""
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"Project-Id-Version: ForkBB\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: ForkBB <mio.visman@yandex.ru>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru\n"
msgid "Must enter title message"
msgstr "Необходимо ввести заголовок группы."
msgid "Title already exists message"
msgstr "Уже есть группа с заголовком <strong>%s</strong>."
msgid "Default group redirect"
msgstr "Установлена группа по умолчанию. Переадресация …"
msgid "Cannot remove default message"
msgstr "Нельзя удалить группу по умолчанию. Чтобы это сделать, вы должны сначала назначить другую группу по умолчанию."
msgid "Group removed redirect"
msgstr "Группа удалена. Переадресация …"
msgid "Group added redirect"
msgstr "Группа добавлена. Переадресация …"
msgid "Group edited redirect"
msgstr "Группа отредактирована. Переадресация …"
msgid "Control of groups"
msgstr "Управление группами"
msgid "Add group subhead"
msgstr "Добавление новой группы"
msgid "New group label"
msgstr "На базе группы"
msgid "New group help"
msgstr "Выберите группу, от которой следует унаследовать права. На следующей странице вы сможете настроить все параметры новой группы."
msgid "Default group subhead"
msgstr "Установка группы по умолчанию"
msgid "Default group label"
msgstr "Группа по умолчанию"
msgid "Default group help"
msgstr "Это группа, в которую попадают вновь зарегистрированные пользователи. По соображениям безопасности, пользователи не должны сразу попадать в Модераторы или Администраторы."
msgid "Existing groups head"
msgstr "Существующие группы"
msgid "Edit groups subhead"
msgstr "Правка/удаление групп"
msgid "Edit groups info"
msgstr "Предустановленные группы Администраторы, Модераторы, Пользователи и Гости не могут быть удалены. Но их можно отредактировать. Не все параметры доступны для редактирования в некоторых группах (например, право <em>Редактировать сообщения</em> для группы Гости). Администраторы всегда имеют полные права."
msgid "Edit link"
msgstr "Править"
msgid "Delete link"
msgstr "Удалить"
msgid "Group delete head"
msgstr "Удаление группы"
msgid "Confirm delete subhead"
msgstr "Подтверждение удаления"
msgid "Confirm delete info"
msgstr "Вы действительно хотите удалить группу <strong>%s</strong>?"
msgid "Confirm delete warn"
msgstr "ВНИМАНИЕ! Удалённую группу невозможно восстановить."
msgid "Delete group head"
msgstr "Удалить группу"
msgid "Move users subhead"
msgstr "Перемещение пользователей группы"
msgid "Move users info"
msgstr "В группе <strong>%s</strong> сейчас состоит <strong>%s</strong> участник(ов). Пожалуйста выберите группу, в которую следует перенести этих пользователей."
msgid "Move users label"
msgstr "Перенести в"
msgid "Delete group"
msgstr "Удалить группу"
msgid "Group settings head"
msgstr "Установки группы"
msgid "Group settings subhead"
msgstr "Установите параметры и права доступа"
msgid "Group settings info"
msgstr "Эти параметры и права являются значениями по умолчанию. Они действуют пока для конкретного раздела не заданы иные значения."
msgid "Group title label"
msgstr "Заголовок группы"
msgid "User title label"
msgstr "Статус пользователя"
msgid "User title help"
msgstr "Ранг пользователей для этой группы. При пустом поле будет использовано значение по умолчанию ('%s')."
msgid "Promote users label"
msgstr "Перемещение пользователей"
msgid "Promote users help"
msgstr "Вы можете переместить пользователя в другую группу автоматически при достижении им заданного числа сообщений. Выберите "%s" для отключения функции. По соображениям безопасности здесь запрещено перемещать в группу администраторов. Изменения для пользователя вступят в силу <strong>сразу</strong>."
msgid "Number for promotion label"
msgstr "Количество сообщений для перемещения"
msgid "Number for promotion help"
msgstr "Считается общее количество сообщений пользователя, а не сообщения, набранные в текущей группе."
msgid "Disable promotion"
msgstr "Перемещение отключено"
msgid "Mod privileges label"
msgstr "Дать модераторские привилегии"
msgid "Mod privileges help"
msgstr "Чтобы пользователь этой группы мог править какой-то раздел, назначьте его модератором этого раздела. Назначение производится в разделе "Модерация" пользовательского профиля."
msgid "Edit profile label"
msgstr "Могут править пользовательские профили"
msgid "Edit profile help"
msgstr "Если модераторские привилегии включены, разрешить пользователям этой группы править профили."
msgid "Rename users label"
msgstr "Могут переименовывать пользователей"
msgid "Rename users help"
msgstr "Если модераторские привилегии включены, разрешить пользователям этой группы переименовывать пользователей."
msgid "Change passwords label"
msgstr "Могут менять пользовательские пароли"
msgid "Change passwords help"
msgstr "Если модераторские привилегии включены, разрешить пользователям этой группы менять пользовательские пароли."
msgid "Mod promote users label"
msgstr "Могут перемещать пользователей"
msgid "Mod promote users help"
msgstr "Если модераторские привилегии включены, разрешить пользователям этой группы перемещать пользователей."
msgid "Ban users label"
msgstr "Могут банить пользователей"
msgid "Ban users help"
msgstr "Если модераторские привилегии включены, разрешить пользователям этой группы банить пользователей."
msgid "Read board label"
msgstr "Читать разделы"
msgid "Read board help"
msgstr "Разрешить пользователям этой группы читать разделы. Эта настройка влияет на все права и НЕ может быть перекрыта для конкретного раздела. Если вы выберете "Нет", пользователи этой группы смогут только войти и выйти."
msgid "View user info label"
msgstr "Видеть информацию о пользователях"
msgid "View user info help"
msgstr "Разрешить пользователям смотреть список пользователей и профили пользователей."
msgid "Post replies label"
msgstr "Комментировать"
msgid "Post replies help"
msgstr "Разрешить пользователям этой группы отвечать в темах."
msgid "Post topics label"
msgstr "Создавать темы"
msgid "Post topics help"
msgstr "Разрешить пользователям этой группы создавать новые темы."
msgid "Edit posts label"
msgstr "Редактировать сообщения"
msgid "Edit posts help"
msgstr "Разрешить пользователям этой группы править их собственные сообщения."
msgid "Delete posts label"
msgstr "Удалять сообщения"
msgid "Delete posts help"
msgstr "Разрешить пользователям этой группы удалять их собственные сообщения."
msgid "Delete topics label"
msgstr "Удалять темы"
msgid "Delete topics help"
msgstr "Разрешить пользователям этой группы удалять их собственные темы (и все комментарии)."
msgid "Post links label"
msgstr "Ссылки в сообщениях"
msgid "Post links help"
msgstr "Разрешить пользователям этой группы использовать ссылки в сообщениях, в своих подписях, а также заполнять поле Сайт в профиле."
msgid "Set own title label"
msgstr "Менять собственный статус"
msgid "Set own title help"
msgstr "Разрешить пользователям этой группы устанавливать собственные статусы."
msgid "User search label"
msgstr "Пользоваться поиском"
msgid "User search help"
msgstr "Разрешить пользователям этой группы пользоваться поиском сообщений."
msgid "User list search label"
msgstr "Искать пользователей"
msgid "User list search help"
msgstr "Разрешить пользователям этой группы пользоваться поиском пользователей."
msgid "Send e-mails label"
msgstr "Посылать Email"
msgid "Send e-mails help"
msgstr "Разрешить пользователям этой группы посылать email другим пользователям."
msgid "Post flood label"
msgstr "Флуд-интервал для сообщений"
msgid "Post flood help"
msgstr "Количество секунд, которые необходимо подождать до написания нового сообщения. Поставьте 0 чтобы выключить ограничение."
msgid "Search flood label"
msgstr "Флуд-интервал для поиска"
msgid "Search flood help"
msgstr "Количество секунд, которые необходимо подождать до нового поиска. Поставьте 0 чтобы выключить ограничение."
msgid "E-mail flood label"
msgstr "Флуд-интервал для Email"
msgid "E-mail flood help"
msgstr "Количество секунд, которые необходимо подождать до отправления следующего email. Поставьте 0 чтобы выключить ограничение."
msgid "Report flood label"
msgstr "Флуд-интервал для сигналов"
msgid "Report flood help"
msgstr "Количество секунд, которые необходимо подождать до отправления следующего сигнала. Поставьте 0 чтобы выключить ограничение."
msgid "Moderator info"
msgstr "Пожалуйста обратите внимание, что пока пользователь не назначен модератором конкретного раздела, он не сможет реализовать свои модераторские права. Назначение производится в разделе "Модерация" пользовательского профиля."

View file

@ -0,0 +1,48 @@
@extends('layouts/admin')
<section class="f-admin">
<h2>{!! __('Group settings head') !!}</h2>
<div class="f-fdiv">
<form class="f-form" method="post" action="{!! $formAction !!}">
<input type="hidden" name="token" value="{!! $formToken !!}">
<dl>
@foreach($form as $key => $cur)
<dt>{!! $cur['title'] !!}</dt>
<dd>
@if($cur['type'] == 'text')
<input class="f-ctrl" @if(isset($cur['required'])){!! 'required' !!}@endif type="text" name="{{ $key }}" maxlength="{!! $cur['maxlength'] !!}" value="{{ $cur['value'] }}" tabindex="{!! ++$tabindex !!}">
@elseif($cur['type'] == 'number')
<input class="f-ctrl" type="number" name="{{ $key }}" min="{!! $cur['min'] !!}" max="{!! $cur['max'] !!}" value="{{ $cur['value'] }}" tabindex="{!! ++$tabindex !!}">
@elseif($cur['type'] == 'select')
<select class="f-ctrl" name="{{ $key }}" tabindex="{!! ++$tabindex !!}">
@foreach($cur['options'] as $v => $n)
@if($v == $cur['value'])
<option value="{{ $v }}" selected>{{ $n }}</option>
@else
<option value="{{ $v }}">{{ $n }}</option>
@endif
@endforeach
</select>
@elseif($cur['type'] == 'radio')
@foreach($cur['values'] as $v => $n)
@if($v == $cur['value'])
<label class="f-label"><input type="radio" name="{{ $key }}" value="{{ $v }}" checked tabindex="{!! ++$tabindex !!}">{{ $n }}</label>
@else
<label class="f-label"><input type="radio" name="{{ $key }}" value="{{ $v }}" tabindex="{!! ++$tabindex !!}">{{ $n }}</label>
@endif
@endforeach
@endif
@if(isset($cur['info']))
<span class="f-child4">{!! $cur['info'] !!}</span>
@endif
</dd>
@endforeach
</dl>
@if($warn)
<p class="f-finfo">{!! $warn !!}</p>
@endif
<div>
<input class="f-btn" type="submit" name="submit" value="{!! __('Save') !!}" tabindex="{!! ++$tabindex !!}">
</div>
</form>
</div>
</section>

View file

@ -0,0 +1,69 @@
@extends('layouts/admin')
<section class="f-admin">
<h2>{!! __('Add group subhead') !!}</h2>
<div class="f-fdiv">
<form class="f-form" method="post" action="{!! $formActionNew !!}">
<input type="hidden" name="token" value="{!! $formTokenNew !!}">
<dl>
<dt>{!! __('New group label') !!}</dt>
<dd>
<select class="f-ctrl" id="id-basegroup" name="basegroup" tabindex="{!! ++$tabindex !!}">
@foreach($groupsNew as $cur)
@if ($cur[0] == $defaultGroup)
<option value="{!! $cur[0] !!}" selected>{{ $cur[1] }}</option>
@else
<option value="{!! $cur[0] !!}">{{ $cur[1] }}</option>
@endif
@endforeach
</select>
<span class="f-child4">{!! __('New group help') !!}</span>
</dd>
</dl>
<div>
<input class="f-btn" type="submit" name="submit" value="{!! __('Add') !!}" tabindex="{!! ++$tabindex !!}">
</div>
</form>
</div>
</section>
<section class="f-admin">
<h2>{!! __('Default group subhead') !!}</h2>
<div class="f-fdiv">
<form class="f-form" method="post" action="{!! $formActionDefault !!}">
<input type="hidden" name="token" value="{!! $formTokenDefault !!}">
<dl>
<dt>{!! __('Default group label') !!}</dt>
<dd>
<select class="f-ctrl" id="id-defaultgroup" name="defaultgroup" tabindex="{!! ++$tabindex !!}">
@foreach($groupsDefault as $cur)
@if ($cur[0] == $defaultGroup)
<option value="{!! $cur[0] !!}" selected>{{ $cur[1] }}</option>
@else
<option value="{!! $cur[0] !!}">{{ $cur[1] }}</option>
@endif
@endforeach
</select>
<span class="f-child4">{!! __('Default group help') !!}</span>
</dd>
</dl>
<div>
<input class="f-btn" type="submit" name="submit" value="{!! __('Save') !!}" tabindex="{!! ++$tabindex !!}">
</div>
</form>
</div>
</section>
<section class="f-admin">
<h2>{!! __('Edit groups subhead') !!}</h2>
<div>
<p>{!! __('Edit groups info') !!}</p>
<ol class="f-grlist">
@foreach($groupsList as $cur)
<li>
<a href="{!! $cur[0] !!}" tabindex="{!! ++$tabindex !!}">{{ $cur[1] }}</a>
@if($cur[2])
<a class="f-btn" href="{!! $cur[2] !!}" tabindex="{!! ++$tabindex !!}">{!! __('Delete link') !!}</a>
@endif
</li>
@endforeach
</ol>
</div>
</section>

View file

@ -1,17 +1,17 @@
@extends('layouts/main')
<section class="f-main f-login">
<div class="f-lrdiv">
<div class="f-fdiv f-lrdiv">
<h2>{!! __('Change pass') !!}</h2>
<form class="f-form" method="post" action="{!! $formAction !!}">
<input type="hidden" name="token" value="{!! $formToken !!}">
<div>
<label class="f-child1 f-req" for="id-password">{!! __('New pass') !!}</label>
<input required class="f-ctrl" id="id-password" type="password" name="password" pattern="^.{16,}$" autofocus="autofocus" tabindex="1">
<input required class="f-ctrl" id="id-password" type="password" name="password" pattern="^.{16,}$" autofocus tabindex="1">
</div>
<div>
<label class="f-child1 f-req" for="id-password2">{!! __('Confirm new pass') !!}</label>
<input required class="f-ctrl" id="id-password2" type="password" name="password2" pattern="^.{16,}$" tabindex="2">
<label class="f-child4">{!! __('Pass format') !!} {!! __('Pass info') !!}</label>
<span class="f-child4">{!! __('Pass format') !!} {!! __('Pass info') !!}</span>
</div>
<div>
<input class="f-btn" type="submit" name="login" value="{!! __('Change passphrase') !!}" tabindex="3">

View file

@ -90,7 +90,7 @@
</div>
</li>
@else
<li id="topic-{!! $topic['id'] !!}" class="f-row<!--inline-->
<li id="topic-{!! $topic['id'] !!}" class="f-row<!-- inline -->
@if($topic['link_new']) f-fnew
@endif
@if($topic['link_unread']) f-funread
@ -103,7 +103,7 @@
@endif
@if($topic['dot']) f-fposted
@endif
"><!--endinline-->
"><!-- endinline -->
<div class="f-cell f-cmain">
<div class="f-ficon"></div>
<div class="f-finfo">

View file

@ -44,7 +44,7 @@
@endif
</dl>
@if($online && $online['list'])
<dl class="f-inline f-onlinelist"><!--inline-->
<dl class="f-inline f-onlinelist"><!-- inline -->
<dt>{!! __('Online') !!}</dt>
@foreach($online['list'] as $cur)
@if(is_string($cur))
@ -53,7 +53,7 @@
<dd><a href="{!! $cur[0] !!}">{{ $cur[1] }}</a></dd>
@endif
@endforeach
</dl><!--endinline-->
</dl><!-- endinline -->
@endif
</div>
</section>

View file

@ -21,7 +21,7 @@
@endif
@if(is_array($installLangs))
<section class="f-install">
<div class="f-lrdiv">
<div class="f-fdiv">
<h2>{!! __('Choose install language') !!}</h2>
<form class="f-form" method="post" action="{!! $formAction !!}">
<div>
@ -46,7 +46,7 @@
@endif
@if(empty($fIswev['e']))
<section class="f-main f-install">
<div class="f-lrdiv">
<div class="f-fdiv">
<h2>{!! __('Install', $rev) !!}</h2>
<form class="f-form" method="post" action="{!! $formAction !!}" autocomplete="off">
<input type="hidden" name="installlang" value="{!! $installLang !!}">

View file

@ -27,18 +27,18 @@
@endif
</h3>
@if($cur['subforums'])
<dl class="f-inline f-fsub"><!--inline-->
<dl class="f-inline f-fsub"><!-- inline -->
<dt>{!! __('Sub forum', count($cur['subforums'])) !!}</dt>
@foreach($cur['subforums'] as $sub)
<dd><a href="{!! $sub[0] !!}">{{ $sub[1] }}</a></dd>
@endforeach
</dl><!--endinline-->
</dl><!-- endinline -->
@endif
@if($cur['forum_desc'])
<p class="f-fdesc">{!! $cur['forum_desc'] !!}</p>
@endif
@if($cur['moderators'])
<dl class="f-inline f-modlist"><!--inline-->
<dl class="f-inline f-modlist"><!-- inline -->
<dt>{!! __('Moderated by') !!}</dt>
@foreach($cur['moderators'] as $mod)
@if(is_string($mod))
@ -47,7 +47,7 @@
<dd><a href="{!! $mod[0] !!}">{{ $mod[1] }}</a></dd>
@endif
@endforeach
</dl><!--endinline-->
</dl><!-- endinline -->
@endif
</div>
</div>

View file

@ -1,13 +1,13 @@
@extends('layouts/main')
<section class="f-main f-login">
<div class="f-lrdiv">
<div class="f-fdiv f-lrdiv">
<h2>{!! __('Login') !!}</h2>
<form class="f-form" method="post" action="{!! $formAction !!}">
<input type="hidden" name="token" value="{!! $formToken !!}">
<input type="hidden" name="redirect" value="{{ $redirect }}">
<div>
<label class="f-child1 f-req" for="id-username">{!! __('Username') !!}</label>
<input required class="f-ctrl" id="id-username" type="text" name="username" value="{{ $username }}" maxlength="25" autofocus="autofocus" spellcheck="false" tabindex="1">
<input required class="f-ctrl" id="id-username" type="text" name="username" value="{{ $username }}" maxlength="25" autofocus spellcheck="false" tabindex="1">
</div>
<div>
<label class="f-child1 f-req" for="id-password">{!! __('Passphrase') !!}<a class="f-forgetlink" href="{!! $forgetLink !!}" tabindex="5">{!! __('Forgotten pass') !!}</a></label>
@ -26,7 +26,7 @@
</form>
</div>
@if($regLink)
<div class="f-lrdiv">
<div class="f-fdiv f-lrdiv">
<p class="f-child3"><a href="{!! $regLink !!}" tabindex="6">{!! __('Not registered') !!}</a></p>
</div>
@endif

View file

@ -1,13 +1,13 @@
@extends('layouts/main')
<section class="f-main f-login">
<div class="f-lrdiv">
<div class="f-fdiv f-lrdiv">
<h2>{!! __('Passphrase reset') !!}</h2>
<form class="f-form" method="post" action="{!! $formAction !!}">
<input type="hidden" name="token" value="{!! $formToken !!}">
<div>
<label class="f-child1 f-req" for="id-email">{!! __('Email') !!}</label>
<input required class="f-ctrl" id="id-email" type="text" name="email" value="{{ $email }}" maxlength="80" pattern=".+@.+" autofocus="autofocus" spellcheck="false" tabindex="1">
<label class="f-child4">{!! __('Passphrase reset info') !!}</label>
<input required class="f-ctrl" id="id-email" type="text" name="email" value="{{ $email }}" maxlength="80" pattern=".+@.+" autofocus spellcheck="false" tabindex="1">
<span class="f-child4">{!! __('Passphrase reset info') !!}</span>
</div>
<div>
<input class="f-btn" type="submit" name="submit" value="{!! __('Send email') !!}" tabindex="2">

View file

@ -1,6 +1,6 @@
@extends('layouts/main')
<section class="f-main f-register">
<div class="f-lrdiv">
<div class="f-fdiv f-lrdiv">
<h2>{!! __('Register') !!}</h2>
<form class="f-form" method="post" action="{!! $formAction !!}">
<input type="hidden" name="token" value="{!! $formToken !!}">
@ -8,21 +8,21 @@
<input type="hidden" name="on" value="{!! $on !!}">
<div>
<label class="f-child1 f-req" for="id-email">{!! __('Email') !!}</label>
<input required class="f-ctrl" id="id-email" type="text" name="email" value="{{ $email }}" maxlength="80" pattern=".+@.+" autofocus="autofocus" spellcheck="false" tabindex="1">
<label class="f-child4 f-fhint">{!! __('Email info') !!}</label>
<input required class="f-ctrl" id="id-email" type="text" name="email" value="{{ $email }}" maxlength="80" pattern=".+@.+" autofocus spellcheck="false" tabindex="1">
<span class="f-child4 f-fhint">{!! __('Email info') !!}</span>
</div>
<div>
<label class="f-child1 f-req" for="id-username">{!! __('Username') !!}</label>
<input required class="f-ctrl" id="id-username" type="text" name="username" value="{{ $username }}" maxlength="25" pattern="^.{2,25}$" spellcheck="false" tabindex="2">
<label class="f-child4 f-fhint">{!! __('Login format') !!}</label>
<span class="f-child4 f-fhint">{!! __('Login format') !!}</span>
</div>
<div>
<label class="f-child1 f-req" for="id-password">{!! __('Passphrase') !!}</label>
<input required class="f-ctrl" id="id-password" type="password" name="password" pattern="^.{16,}$" tabindex="3">
<label class="f-child4 f-fhint">{!! __('Pass format') !!} {!! __('Pass info') !!}</label>
<span class="f-child4 f-fhint">{!! __('Pass format') !!} {!! __('Pass info') !!}</span>
</div>
<div>
<input class="f-btn" type="submit" name="register" value="{!! __('Sign up') !!}" tabindex="5">
<input class="f-btn" type="submit" name="register" value="{!! __('Sign up') !!}" tabindex="4">
</div>
</form>
</div>

View file

@ -3,7 +3,7 @@
<h2>{!! $title !!}</h2>
<div id="id-rules">{!! $rules !!}</div>
@if($formAction)
<div class="f-lrdiv">
<div class="f-fdiv f-lrdiv">
<form class="f-form" method="post" action="{!! $formAction !!}">
<input type="hidden" name="token" value="{!! $formToken !!}">
<div>

View file

@ -370,6 +370,114 @@ select {
background-color: #FFCCBA;
}
/*********/
/* Формы */
/*********/
.f-fdiv {
max-width: 100%;
border: 0.0625rem solid #AA7939;
}
.f-fdiv h2,
.f-fdiv .f-form {
padding: 0.625rem;
}
.f-fdiv h3 {
padding: 0.625rem 0.625rem 0 0.625rem;
}
.f-fdiv .f-ctrl,
.f-fdiv .f-btn {
padding: 0.5rem;
font-size: 1rem;
display: block;
width: 100%;
margin-bottom: 1rem;
box-sizing: border-box;
}
.f-fdiv .f-label {
font-size: 1rem;
margin-bottom: 1rem;
display: inline-block;
}
.f-fdiv .f-label > input {
margin-left: 0;
margin-right: 0.3125rem;
}
.f-fdiv .f-label + .f-label {
margin-left: 0.625rem;
}
.f-fdiv .f-child1,
.f-fdiv .f-child2,
.f-fdiv .f-child3,
.f-fdiv .f-child4 {
display: block;
width: 100%;
}
.f-fdiv .f-child1 {
font-weight: bold;
}
.f-fdiv .f-child2 {
font-size: 0.875rem;
}
.f-fdiv .f-child2 > input {
margin: 0 0.625rem 0 0;
}
.f-fdiv .f-btn {
margin: 1rem 0 0.375rem 0;
}
.f-fdiv .f-child3 {
padding: 0.625rem;
text-align: center;
font-size: 0.875rem;
}
.f-fdiv .f-child4 {
font-size: 0.8125rem;
text-align: justify;
}
.f-fdiv .f-finfo {
margin: 1rem -0.625rem;
background-color: #AA7939;
padding: 0.625rem;
color: #F8F4E3;
}
.f-ctrl {
border: 0.0625rem solid #AA7939;
}
.f-ctrl:focus {
box-shadow: inset 0px 0px 0.25rem 0 rgba(170,121,57,0.5), 0px 0px 0.25rem 0 rgba(170,121,57,0.5);
}
.f-ctrl + .f-fhint {
overflow: hidden;
max-height: 0;
-webkit-transition: max-height 0.5s, margin 0.5s;
-webkit-transition-delay: 0.2s;
transition: max-height 0.5s, margin 0.5s;
transition-delay: 0.2s;
}
.f-ctrl:focus + .f-fhint,
.f-ctrl:active + .f-fhint {
margin-top: -0.375rem;
margin-bottom: 1rem;
max-height: 1000rem;
}
/**************/
/* Объявление */
/**************/
@ -757,8 +865,8 @@ li + li .f-btn {
}
.f-admin-menu .f-menu-items li {
// min-width: 4rem;
// float: left;
/* min-width: 4rem; */
/* float: left; */
}
.f-admin-menu a {
@ -779,7 +887,7 @@ li + li .f-btn {
/* Админка */
/***********/
.f-admin > h2 {
padding-top: 0.625rem;
padding: 0.625rem 0.625rem 0 0.625rem;
}
.f-admin > div {
@ -790,6 +898,7 @@ li + li .f-btn {
.f-admin > div > p {
padding: 0.625rem;
text-align: justify;
}
.f-admin > div > ul {
@ -803,7 +912,7 @@ li + li .f-btn {
}
.f-admin dt {
padding: 0.625rem 0;
padding-top: 0.625rem;
}
.f-admin dd {
@ -811,13 +920,36 @@ li + li .f-btn {
border-bottom: 0.0625rem dotted #AA7939;
}
.f-admin .f-fdiv dl {
margin: 0;
}
.f-grlist {
padding: 0.625rem;
}
.f-grlist > li {
padding: 0.625rem 0;
border-bottom: 0.0625rem dotted #AA7939;
}
.f-grlist > li:first-child {
border-top: 0.0625rem dotted #AA7939;
}
.f-grldelete {
font-size: 0.875rem;
white-space: nowrap;
}
@media screen and (min-width: 36rem) {
.f-admin dt {
float: left;
width: 14rem;
}
.f-admin dd {
padding-left: 14rem;
padding-left: 14.625rem;
}
}
@ -865,107 +997,24 @@ li + li .f-btn {
.f-lrdiv {
margin: 1rem auto;
max-width: 20rem;
border: 0.0625rem solid #AA7939;
border-radius: 0.1875rem;
}
.f-lrdiv h2 {
padding: 0.625rem;
text-align: center;
}
.f-lrdiv .f-form {
padding: 0.625rem;
}
.f-lrdiv .f-ctrl,
.f-lrdiv .f-btn {
padding: 0.5rem;
font-size: 1rem;
display: block;
width: 100%;
margin-bottom: 1rem;
box-sizing: border-box;
}
.f-lrdiv .f-child1,
.f-lrdiv .f-child2,
.f-lrdiv .f-child3,
.f-lrdiv .f-child4 {
display: block;
width: 100%;
}
.f-forgetlink {
font-size: 0.875rem;
float: right;
font-weight: normal;
}
.f-lrdiv .f-child1 {
font-weight: bold;
}
.f-lrdiv .f-child2 {
font-size: 0.875rem;
}
.f-lrdiv .f-child2 > input {
margin: 0 0.625rem 0 0;
}
.f-lrdiv .f-btn {
margin: 1rem 0 0.375rem 0;
}
.f-lrdiv .f-child3 {
padding: 0.625rem;
text-align: center;
font-size: 0.875rem;
}
.f-lrdiv .f-child4 {
font-size: 0.8125rem;
text-align: justify;
}
.f-ctrl {
border: 0.0625rem solid #AA7939;
}
.f-ctrl:focus {
box-shadow: inset 0px 0px 0.25rem 0 rgba(170,121,57,0.5), 0px 0px 0.25rem 0 rgba(170,121,57,0.5);
}
.f-ctrl + .f-fhint {
overflow: hidden;
max-height: 0;
-webkit-transition: max-height 0.5s, margin 0.5s;
-webkit-transition-delay: 0.2s;
transition: max-height 0.5s, margin 0.5s;
transition-delay: 0.2s;
}
.f-ctrl:focus + .f-fhint,
.f-ctrl:active + .f-fhint {
margin-top: -0.375rem;
margin-bottom: 1rem;
max-height: 1000rem;
}
/*************/
/* Установка */
/*************/
.f-install .f-lrdiv {
.f-install .f-fdiv {
margin: 1rem 0;
max-width: 100%;
}
.f-lrdiv .f-finfo {
margin: 1rem -0.625rem;
background-color: #AA7939;
padding: 0.625rem;
color: #F8F4E3;
}
.f-install .f-ctrl + .f-child4 {