Forráskód Böngészése

Add subscriptions 2

In profile and in users/forums/topics deleting
Visman 4 éve
szülő
commit
c55b439bc9

+ 3 - 1
app/Models/Forum/Delete.php

@@ -63,7 +63,7 @@ class Delete extends Action
 
         $this->c->topics->delete(...$args);
 
-        //???? подписки, опросы, предупреждения
+        //???? опросы, предупреждения
 
         if ($users) {
             $vars  = [
@@ -78,6 +78,8 @@ class Delete extends Action
             //???? удаление модераторов из разделов
         }
         if ($forums) {
+            $this->c->subscriptions->unsubscribe(...$forums);
+
             foreach ($forums as $forum) {
                 $this->c->groups->Perm->reset($forum);
             }

+ 37 - 0
app/Models/Pages/Profile/View.php

@@ -274,6 +274,43 @@ class View extends Profile
                 ];
             }
         }
+        if ($this->rules->viewSubscription) {
+            $subscr     = $this->c->subscriptions;
+            $subscrInfo = $subscr->info($this->curUser);
+            $isLink     = '1' == $this->user->g_search;
+            if (! empty($subscrInfo[$subscr::FORUMS_DATA])) {
+                $fields['forums_subscr'] = [
+                    'class'   => 'pline',
+                    'type'    => $isLink ? 'link' : 'str',
+                    'caption' => __('Total forums subscriptions'),
+                    'value'   => \ForkBB\num(\count($subscrInfo[$subscr::FORUMS_DATA])),
+                    'href'    => $this->c->Router->link(
+                        'SearchAction',
+                        [
+                            'action' => 'forums_subscriptions',
+                            'uid'    => $this->curUser->id,
+                        ]
+                    ),
+                    'title'   => __('Show forums subscriptions'),
+                ];
+            }
+            if (! empty($subscrInfo[$subscr::TOPICS_DATA])) {
+                $fields['topics_subscr'] = [
+                    'class'   => 'pline',
+                    'type'    => $isLink ? 'link' : 'str',
+                    'caption' => __('Total topics subscriptions'),
+                    'value'   => \ForkBB\num(\count($subscrInfo[$subscr::TOPICS_DATA])),
+                    'href'    => $this->c->Router->link(
+                        'SearchAction',
+                        [
+                            'action' => 'topics_subscriptions',
+                            'uid'    => $this->curUser->id,
+                        ]
+                    ),
+                    'title'   => __('Show topics subscriptions'),
+                ];
+            }
+        }
         $form['sets']['activity'] = [
             'class'  => 'data',
             'legend' => __('User activity'),

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

@@ -149,4 +149,16 @@ class Profile extends Rules
     {
         return $this->my || $this->admin;
     }
+
+    protected function getviewSubscription(): bool
+    {
+        return (
+                $this->my
+                || $this->admin
+            )
+            && (
+                '1' == $this->c->config->o_forum_subscriptions
+                || '1' == $this->c->config->o_topic_subscriptions
+            );
+    }
 }

+ 119 - 46
app/Models/Subscription/Model.php

@@ -7,8 +7,8 @@ use ForkBB\Models\DataModel;
 use ForkBB\Models\Forum\Model as Forum;
 use ForkBB\Models\Topic\Model as Topic;
 use ForkBB\Models\User\Model as User;
+use PDO;
 use InvalidArgumentException;
-use PDOException;
 
 class Model extends ParentModel
 {
@@ -22,24 +22,41 @@ class Model extends ParentModel
      */
     protected $topics;
 
+    /**
+     * @var array
+     */
+    protected $users;
+
     /**
      * Проверяет список моделей на форумы/темы
      * Заполняет $forums и $topics
      */
-    protected function check(array $models): void
+    protected function check(array $models, bool $mayBeUsers = false): void
     {
         $this->forums = [];
         $this->topics = [];
+        $this->users  = [];
 
         if (empty($models)) {
-            throw new InvalidArgumentException('Expected at least one Forum or Topic');
+            if ($mayBeUsers) {
+                throw new InvalidArgumentException('Expected at least one Forum, Topic or User');
+            } else {
+                throw new InvalidArgumentException('Expected at least one Forum or Topic');
+            }
         }
 
         foreach ($models as $model) {
-            if ($model instanceof Forum) {
+            if (
+                $mayBeUsers
+                && $model instanceof User
+            ) {
+                $this->users[$model->id] = $model->id;
+            } elseif ($model instanceof Forum) {
                 $this->forums[$model->id] = $model->id;
+                $mayBeUsers               = false;
             } elseif ($model instanceof Topic) {
                 $this->topics[$model->id] = $model->id;
+                $mayBeUsers               = false;
             } else {
                 throw new InvalidArgumentException('Expected only Forum or Topic');
             }
@@ -104,63 +121,119 @@ class Model extends ParentModel
     }
 
     /**
-     * Отписывает юзера/всех юзеров от форума(ов)/тем(ы)
+     * Отписывает юзеров от форумов/топиков
+     * Убирает подписки с удаляемых форумов/топиков
+     * Убирает подписки с удаляемых юзеров
      */
-    public function unsubscribe(?User $user, DataModel ...$models): bool
+    public function unsubscribe(DataModel ...$models): bool
     {
-        if ($user instanceof User) {
-            if (
-                $user->isGuest
-                || $user->isUnverified
-            ) {
-                return false;
-            }
-
-            $vars = [
-                ':uid' => $user->id,
-            ];
-        } else {
-            $vars = [];
-        }
+        $where = [];
+        $vars  = [];
 
-        $this->check($models);
+        $this->check($models, true);
 
-        if (! empty($this->forums)) {
-            if (isset($vars[':uid'])) {
-                $query = 'DELETE
-                    FROM ::forum_subscriptions
-                    WHERE user_id=?i:uid AND forum_id=?i:id';
+        if (! empty($this->users)) {
+            if (1 === \count($this->users)) {
+                $where[':uid'] = 'user_id=?i:uid';
+                $vars[':uid']  = \reset($this->users);
             } else {
-                $query = 'DELETE
-                    FROM ::forum_subscriptions
-                    WHERE forum_id=?i:id';
+                $where[':uid'] = 'user_id IN(?ai:uid)';
+                $vars[':uid']  = $this->users;
             }
+        }
 
-            foreach ($this->forums as $id) {
-                $vars[':id'] = $id;
-
-                $this->c->DB->exec($query, $vars);
+        $all = empty($this->forums) && empty($this->topics);
+
+        if ($all || ! empty($this->forums)) {
+            if (! empty($this->forums)) {
+                if (1 === \count($this->forums)) {
+                    $where[':id'] = 'forum_id=?i:id';
+                    $vars[':id']  = \reset($this->forums);
+                } else {
+                    $where[':id'] = 'forum_id IN(?ai:id)';
+                    $vars[':id']  = $this->forums;
+                }
             }
+
+            $query = 'DELETE
+                FROM ::forum_subscriptions
+                WHERE ' . \implode(' AND ', $where);
+
+            $this->c->DB->exec($query, $vars);
         }
 
-        if (! empty($this->topics)) {
-            if (isset($vars[':uid'])) {
-                $query = 'DELETE
-                    FROM ::topic_subscriptions
-                    WHERE user_id=?i:uid AND topic_id=?i:id';
-            } else {
-                $query = 'DELETE
-                    FROM ::topic_subscriptions
-                    WHERE topic_id=?i:id';
+        unset($where[':id'], $vars[':id']);
+
+        if ($all || ! empty($this->topics)) {
+            if (! empty($this->topics)) {
+                if (1 === \count($this->topics)) {
+                    $where[':id'] = 'topic_id=?i:id';
+                    $vars[':id']  = \reset($this->topics);
+                } else {
+                    $where[':id'] = 'topic_id IN(?ai:id)';
+                    $vars[':id']  = $this->topics;
+                }
             }
 
-            foreach ($this->topics as $id) {
-                $vars[':id'] = $id;
+            $query = 'DELETE
+                FROM ::topic_subscriptions
+                WHERE ' . \implode(' AND ', $where);
 
-                $this->c->DB->exec($query, $vars);
-            }
+            $this->c->DB->exec($query, $vars);
         }
 
         return true;
     }
+
+    const FORUMS_DATA = 1;
+    const TOPICS_DATA = 2;
+    const ALL_DATA    = 3;
+
+    /**
+     * Возвращает информацию по подпискам
+     */
+    public function info(DataModel $model, int $type = self::ALL_DATA): array
+    {
+        $result = [];
+
+        if ($model instanceof User) {
+            $vars = [
+                ':uid' => $model->id,
+            ];
+
+            if (self::FORUMS_DATA & $type) {
+                if (
+                    '1' != $this->c->config->o_forum_subscriptions
+                    || $model->isGuest
+                ) {
+                    $result[self::FORUMS_DATA] = null;
+                } else {
+                    $query = 'SELECT forum_id
+                        FROM ::forum_subscriptions
+                        WHERE user_id=?i:uid';
+
+                    $result[self::FORUMS_DATA] = $this->c->DB->query($query, $vars)->fetchAll(PDO::FETCH_COLUMN);
+                }
+            }
+
+            if (self::TOPICS_DATA & $type) {
+                if (
+                    '1' != $this->c->config->o_topic_subscriptions
+                    || $model->isGuest
+                ) {
+                    $result[self::TOPICS_DATA] = null;
+                } else {
+                    $query = 'SELECT topic_id
+                        FROM ::topic_subscriptions
+                        WHERE user_id=?i:uid';
+
+                    $result[self::TOPICS_DATA] = $this->c->DB->query($query, $vars)->fetchAll(PDO::FETCH_COLUMN);
+                }
+            }
+        } else {
+            throw new InvalidArgumentException('Expected only User');
+        }
+
+        return $result;
+    }
 }

+ 3 - 1
app/Models/Topic/Delete.php

@@ -119,7 +119,7 @@ class Delete extends Action
 
         $this->c->posts->delete(...$args);
 
-        //???? подписки, опросы, предупреждения
+        //???? опросы, предупреждения
 
         // удаление тем-ссылок на удаляемые темы
 
@@ -170,6 +170,8 @@ class Delete extends Action
             $this->c->DB->exec($query, $vars);
         }
         if ($topics) {
+            $this->c->subscriptions->unsubscribe(...$topics);
+
             $vars  = [
                 ':topics' => \array_keys($topics),
             ];

+ 2 - 1
app/Models/User/Delete.php

@@ -57,8 +57,9 @@ class Delete extends Action
         }
 
         $this->c->forums->delete(...$users);
+        $this->c->subscriptions->unsubscribe(...$users);
 
-        //???? подписки, опросы, предупреждения
+        //???? опросы, предупреждения
 
         foreach ($users as $user) {
             $this->c->Online->delete($user);

+ 12 - 0
app/lang/en/profile.po

@@ -533,3 +533,15 @@ msgstr "Strict"
 
 msgid "IP check info"
 msgstr "<b>Strict</b> - if your ip address has changed, you will be logout;<br><b>Not strict</b> - this board remembers 10-20 of your last ip addresses and if your current ip address is not in this list, you will be logout;<br><b>Off</b> - changing your ip address does not affect anything."
+
+msgid "Total topics subscriptions"
+msgstr "Total topics subscriptions"
+
+msgid "Total forums subscriptions"
+msgstr "Total forums subscriptions"
+
+msgid "Show topics subscriptions"
+msgstr "Show user subscriptions to topics"
+
+msgid "Show forums subscriptions"
+msgstr "Show user subscriptions to forums"

+ 12 - 0
app/lang/ru/profile.po

@@ -533,3 +533,15 @@ msgstr "Строгая"
 
 msgid "IP check info"
 msgstr "<b>Строгая</b> - при каждой смене вашего ip адреса, вы будите разлогинены;<br><b>Не строгая</b> - форум помнит 10-20 ваших последних ip адресов и если ваш текущий ip адрес не попадает в этот список, вы будите разлогинены;<br><b>Отключена</b> - смена вашего ip адеса ни на что не влияет."
+
+msgid "Total topics subscriptions"
+msgstr "Всего подписок на темы"
+
+msgid "Total forums subscriptions"
+msgstr "Всего подписок на разделы"
+
+msgid "Show topics subscriptions"
+msgstr "Показать подписки пользователя на темы"
+
+msgid "Show forums subscriptions"
+msgstr "Показать подписки пользователя на разделы"