Explorar o código

+ Added moderator rights management

Visman %!s(int64=6) %!d(string=hai) anos
pai
achega
c7891988a9

+ 2 - 1
app/Controllers/Routing.php

@@ -85,8 +85,9 @@ class Routing
                 $r->add('GET',           '/user/{id:[2-9]|[1-9]\d+}/{name}',          'ProfileView:view',   'User');
                 $r->add(['GET', 'POST'], '/user/{id:[2-9]|[1-9]\d+}/edit/profile',    'ProfileEdit:edit',   'EditUserProfile');
                 $r->add(['GET', 'POST'], '/user/{id:[2-9]|[1-9]\d+}/edit/config',     'ProfileConfig:config', 'EditUserBoardConfig');
-                $r->add(['GET', 'POST'], '/user/{id:[2-9]|[1-9]\d+}/edit/email',      'ProfileEmail:email',  'EditUserEmail');
+                $r->add(['GET', 'POST'], '/user/{id:[2-9]|[1-9]\d+}/edit/email',      'ProfileEmail:email', 'EditUserEmail');
                 $r->add(['GET', 'POST'], '/user/{id:[2-9]|[1-9]\d+}/edit/passphrase', 'ProfilePass:pass',   'EditUserPass');
+                $r->add(['GET', 'POST'], '/user/{id:[2-9]|[1-9]\d+}/edit/moderation', 'ProfileMod:moderation', 'EditUserModeration');
             } elseif (! $user->isGuest) {
                 // только свой профиль
                 $r->add('GET',           '/user/{id:' . $user->id . '}/{name}',          'ProfileView:view',   'User');

+ 22 - 1
app/Models/Forum/Model.php

@@ -176,6 +176,27 @@ class Model extends DataModel
         }
     }
 
+    /**
+     * Добавляет указанных пользователей в списка модераторов
+     *
+     * @param array ...$users
+     *
+     * @throws InvalidArgumentException
+     */
+    public function modAdd(...$users)
+    {
+        $moderators = empty($this->a['moderators']) ? [] : $this->a['moderators'];
+
+        foreach ($users as $user) {
+            if (! $user instanceof User) {
+                throw new InvalidArgumentException('Expected User');
+            }
+            $moderators[$user->id] = $user->username;
+        }
+
+        $this->moderators = $moderators;
+    }
+
     /**
      * Удаляет указанных пользователей из списка модераторов
      *
@@ -330,7 +351,7 @@ class Model extends DataModel
     {
         $data = parent::getAttrs();
 
-        $data['moderators'] = empty($data['moderators']) ? null : \json_encode($data['moderators']);
+        $data['moderators'] = empty($data['moderators']) ? '' : \json_encode($data['moderators']);
 
         return $data;
     }

+ 15 - 16
app/Models/Pages/Profile/Edit.php

@@ -196,10 +196,6 @@ class Edit extends Profile
 
         // имя, титул и аватара
         $fields = [];
-        $fields['usertitle'] = [
-            'class' => 'usertitle',
-            'type'  => 'wrap',
-        ];
         if ($this->rules->rename) {
             $fields['username'] = [
                 'type'      => 'text',
@@ -217,14 +213,6 @@ class Edit extends Profile
                 'value'   => $this->curUser->username,
             ];
         }
-        if ($this->rules->editPass) {
-            $fields['change_pass'] = [
-                'type'  => 'link',
-                'value' => \ForkBB\__('Change passphrase'),
-                'href'  => $this->c->Router->link('EditUserPass', ['id' => $this->curUser->id]),
-            ];
-        }
-
         if ($this->rules->changeGroup) {
             $fields['group'] = [
                 'type'    => 'link',
@@ -241,7 +229,14 @@ class Edit extends Profile
                 'value'   => $this->curUser->group_id ? $this->curUser->g_title : '-',
             ];
         }
-
+        if ($this->rules->confModer) {
+            $fields['configure-moderator'] = [
+                'type'    => 'link',
+                'value'   => \ForkBB\__('Configure moderator rights'),
+                'title'   => \ForkBB\__('Configure moderator rights'),
+                'href'    => $this->c->Router->link('EditUserModeration', ['id' => $this->curUser->id]),
+            ];
+        }
         if ($this->rules->setTitle) {
             $fields['title'] = [
                 'type'      => 'text',
@@ -258,9 +253,13 @@ class Edit extends Profile
                 'value'   => $this->curUser->title(),
             ];
         }
-        $fields[] = [
-            'type' => 'endwrap',
-        ];
+        if ($this->rules->editPass) {
+            $fields['change_pass'] = [
+                'type'  => 'link',
+                'value' => \ForkBB\__('Change passphrase'),
+                'href'  => $this->c->Router->link('EditUserPass', ['id' => $this->curUser->id]),
+            ];
+        }
         if ($this->rules->useAvatar) {
             if (! $this->curUser->avatar) {
                 $fields['avatar'] = [

+ 148 - 0
app/Models/Pages/Profile/Mod.php

@@ -0,0 +1,148 @@
+<?php
+
+namespace ForkBB\Models\Pages\Profile;
+
+use ForkBB\Core\Image;
+use ForkBB\Core\Validator;
+use ForkBB\Models\Pages\Profile;
+use ForkBB\Models\User\Model as User;
+use ForkBB\Models\Forum\Model as Forum;
+use ForkBB\Models\Forum\Manager as ForumManager;
+
+class Mod extends Profile
+{
+    /**
+     * Подготавливает данные для шаблона конфигурации прав модератора
+     *
+     * @param array $args
+     * @param string $method
+     *
+     * @return Page
+     */
+    public function moderation(array $args, $method)
+    {
+        if (false === $this->initProfile($args['id']) || ! $this->rules->confModer) {
+            return $this->c->Message->message('Bad request');
+        }
+
+        if ('POST' === $method) {
+            $v = $this->c->Validator->reset()
+                ->addValidators([
+                ])->addRules([
+                    'token'       => 'token:EditUserModeration',
+                    'moderator.*' => 'integer|in:' . \implode(',', \array_keys($this->curForums)),
+                ])->addAliases([
+                ])->addArguments([
+                    'token'       => ['id' => $this->curUser->id],
+                ])->addMessages([
+                ]);
+
+            if ($v->validation($_POST)) {
+                foreach ($this->c->forums->get(0)->descendants as $forum) {
+                    if (isset($v->moderator[$forum->id]) && $v->moderator[$forum->id] === $forum->id) {
+                        $forum->modAdd($this->curUser);
+                    } else {
+                        $forum->modDelete($this->curUser);
+                    }
+                    $this->c->forums->update($forum);
+                }
+
+                $this->c->Cache->delete('forums_mark');
+
+                return $this->c->Redirect->page('EditUserModeration', ['id' => $this->curUser->id])->message('Update rights redirect');
+            }
+
+            $this->fIswev = $v->getErrors();
+        }
+
+        $this->crumbs     = $this->crumbs(
+            [$this->c->Router->link('EditUserModeration', ['id' => $this->curUser->id]), \ForkBB\__('Moderator rights')],
+            [$this->c->Router->link('EditUserProfile', ['id' => $this->curUser->id]), \ForkBB\__('Editing profile')]
+        );
+        $this->form       = $this->form();
+        $this->actionBtns = $this->btns('edit');
+
+        return $this;
+    }
+
+    /**
+     * Возвращает список доступных разделов для пользователя текущего профиля
+     *
+     * @return array
+     */
+    protected function getcurForums()
+    {
+        $forums = new ForumManager($this->c);
+        $forums->init($this->c->groups->get($this->curUser->group_id));
+        $root = $forums->get(0);
+
+        return $root instanceof Forum ? $root->descendants : [];
+    }
+
+    /**
+     * Создает массив данных для формы
+     *
+     * @return array
+     */
+    protected function form()
+    {
+        $form = [
+            'action' => $this->c->Router->link('EditUserModeration', ['id' => $this->curUser->id]),
+            'hidden' => [
+                'token' => $this->c->Csrf->create('EditUserModeration', ['id' => $this->curUser->id]),
+            ],
+            'sets'   => [],
+            'btns'   => [
+                'save' => [
+                    'type'      => 'submit',
+                    'value'     => \ForkBB\__('Save'),
+                    'accesskey' => 's',
+                ],
+            ],
+        ];
+
+        $root = $this->c->forums->get(0);
+
+        if ($root instanceof Forum) {
+            $list = $this->c->forums->depthList($root, 0);
+            $cid  = null;
+
+            foreach ($list as $forum) {
+                if ($cid !== $forum->cat_id) {
+                    $form['sets']["category{$forum->cat_id}-info"] = [
+                        'info' => [
+                            'info1' => [
+                                'type'  => '', //????
+                                'value' => $forum->cat_name,
+                            ],
+                        ],
+                    ];
+                    $cid = $forum->cat_id;
+                }
+
+                $fields = [];
+                $fields["name{$forum->id}"] = [
+                    'class'   => ['modforum', 'name', 'depth' . $forum->depth],
+                    'type'    => 'str',
+                    'value'   => $forum->forum_name,
+                    'caption' => \ForkBB\__('Forum label'),
+                ];
+                $fields["moderator[{$forum->id}]"] = [
+                    'class'    => ['modforum', 'moderator'],
+                    'type'     => 'checkbox',
+                    'value'    => $forum->id,
+                    'checked'  => isset($this->curForums[$forum->id]) && $this->curUser->isModerator($forum),
+                    'disabled' => ! isset($this->curForums[$forum->id]),
+                    'caption'  => \ForkBB\__('Moderator label'),
+                ];
+                $form['sets']["forum{$forum->id}"] = [
+                    'class'  => 'modforum',
+                    'legend' => $forum->cat_name . ' / ' . $forum->forum_name,
+                    'fields' => $fields,
+                ];
+            }
+        }
+
+        return $form;
+    }
+}

+ 5 - 0
app/Models/Rules/Profile.php

@@ -114,4 +114,9 @@ class Profile extends Rules
     {
         return $this->admin || ($this->my && $this->moderator);
     }
+
+    protected function getconfModer()
+    {
+        return $this->user->isAdmin && $this->curUser->isAdmMod && ! $this->curUser->isAdmin;
+    }
 }

+ 2 - 1
app/config/main.dist.php

@@ -156,7 +156,8 @@ return [
         'ProfileEdit'     => \ForkBB\Models\Pages\Profile\Edit::class,
         'ProfileConfig'   => \ForkBB\Models\Pages\Profile\Config::class,
         'ProfilePass'     => \ForkBB\Models\Pages\Profile\Pass::class,
-        'ProfileEmail'     => \ForkBB\Models\Pages\Profile\Email::class,
+        'ProfileEmail'    => \ForkBB\Models\Pages\Profile\Email::class,
+        'ProfileMod'      => \ForkBB\Models\Pages\Profile\Mod::class,
         'AdminIndex'      => \ForkBB\Models\Pages\Admin\Index::class,
         'AdminStatistics' => \ForkBB\Models\Pages\Admin\Statistics::class,
         'AdminOptions'    => \ForkBB\Models\Pages\Admin\Options::class,

+ 13 - 1
app/lang/en/profile.po

@@ -375,7 +375,7 @@ msgstr "User deleted. Redirecting …"
 msgid "Group membership redirect"
 msgstr "Group membership saved. Redirecting …"
 
-msgid "Update forums redirect"
+msgid "Update rights redirect"
 msgstr "Forum moderator rights updated. Redirecting …"
 
 msgid "Ban redirect"
@@ -518,3 +518,15 @@ msgstr "Group"
 
 msgid "Change user group"
 msgstr "Change user group"
+
+msgid "Configure moderator rights"
+msgstr "Configure moderator rights"
+
+msgid "Moderator rights"
+msgstr "Moderator rights"
+
+msgid "Forum label"
+msgstr "Forum"
+
+msgid "Moderator label"
+msgstr "Moderator"

+ 13 - 1
app/lang/ru/profile.po

@@ -375,7 +375,7 @@ msgstr "Пользователь удален. Переадресация &helli
 msgid "Group membership redirect"
 msgstr "Группа пользователя изменена. Переадресация &hellip;"
 
-msgid "Update forums redirect"
+msgid "Update rights redirect"
 msgstr "Права модератора обновлены. Переадресация &hellip;"
 
 msgid "Ban redirect"
@@ -518,3 +518,15 @@ msgstr "Группа"
 
 msgid "Change user group"
 msgstr "Изменить группу пользователя"
+
+msgid "Configure moderator rights"
+msgstr "Настроить права модератора"
+
+msgid "Moderator rights"
+msgstr "Права модератора"
+
+msgid "Forum label"
+msgstr "Раздел"
+
+msgid "Moderator label"
+msgstr "Модератор"

+ 33 - 0
public/style/ForkBB/style.css

@@ -2297,6 +2297,39 @@ body,
   }
 }
 
+#fork .f-fs-modforum {
+  display: flex;
+  align-items: stretch;
+}
+
+#fork .f-fs-modforum > dl {
+  border-bottom: 0.0625rem dotted #AA7939;
+  margin-bottom: 0.3125rem;
+}
+
+#fork .f-fs-modforum > legend,
+#fork .f-field-modforum > dt {
+  display: none;
+}
+
+#fork .f-fs-modforum .f-child2 > input {
+  margin: 0;
+}
+
+#fork .f-fs-modforum .f-child1 {
+  font-weight: normal;
+}
+
+#fork .f-field-modforum.f-field-moderator {
+  width: 3rem;
+  overflow: hidden;
+  text-align: center;
+}
+
+#fork .f-field-modforum.f-field-name {
+  width: calc(100% - 3rem);
+}
+
 /****************************/
 /* Профиль - редактирование */
 /****************************/