Visman %!s(int64=7) %!d(string=hai) anos
pai
achega
09066ad1db

+ 1 - 0
app/Models/Page.php

@@ -194,6 +194,7 @@ class Page extends Model
         if (! empty($status = $this->httpStatus())) {
             $headers[] = $status;
         }
+#       $headers[] = 'X-Frame-Options: DENY';
         return $headers;
     }
 

+ 11 - 0
app/Models/Pages/Delete.php

@@ -117,7 +117,18 @@ class Delete extends Page
             return $this->c->Redirect->page('ViewPost', $args)->message(\ForkBB\__('No confirm redirect'));
         }
 
+        $this->c->DB->beginTransaction();
+
+        if ($deleteTopic) {
+            $redirect = $this->c->Redirect->page('Forum', ['id' => $topic->forum_id])->message(\ForkBB\__('Topic del redirect'));
+            $this->c->topics->delete($topic);
+        } else {
+            $redirect = $this->c->Redirect->page('ViewPost', ['id' => $this->c->posts->previousPost($post)])->message(\ForkBB\__('Post del redirect'));
+            $this->c->posts->delete($post);
+        }
 
+        $this->c->DB->commit();
 
+        return $redirect;
     }
 }

+ 1 - 1
app/Models/Pages/Edit.php

@@ -165,7 +165,7 @@ class Edit extends Page
         // антифлуд 
         if ($calcPost || $calcForum) { 
             $user->last_post = $now; //????
-            $user->update();
+            $this->c->users->update($user);
         }
         
         return $this->c->Redirect

+ 1 - 1
app/Models/Pages/Post.php

@@ -259,7 +259,7 @@ class Post extends Page
             }
         }
         $user->last_post = $now;
-        $user->update();
+        $this->c->users->update($user);
         
         return $this->c->Redirect
             ->page('ViewPost', ['id' => $merge ? $lastPost->id : $post->id])

+ 3 - 2
app/Models/Pages/Register.php

@@ -244,8 +244,9 @@ class Register extends Page
         $user->group_id = $this->c->config->o_default_user_group;
         $user->email_confirmed = 1;
         $user->activate_string = null;
-        $user->update();
-        $this->c->{'users_info update'};
+        $this->c->users->update($user);
+
+        $this->c->{'users_info update'}; //????
 
         $this->c->Lang->load('register');
 

+ 122 - 0
app/Models/Post/Delete.php

@@ -0,0 +1,122 @@
+<?php
+
+namespace ForkBB\Models\Post;
+
+use ForkBB\Models\Action;
+use ForkBB\Models\Forum\Model as Forum;
+use ForkBB\Models\Post\Model as Post;
+use ForkBB\Models\Topic\Model as Topic;
+use InvalidArgumentException;
+use RuntimeException;
+
+class Delete extends Action
+{
+    /**
+     * Удаляет тему(ы) 
+     *
+     * @param mixed ...$args
+     *
+     * @throws InvalidArgumentException
+     * @throws RuntimeException
+     */
+    public function delete(...$args)
+    {
+        if (empty($args)) {
+            throw new InvalidArgumentException('No arguments, expected forum, topic or post');
+        }
+
+        $posts   = [];
+        $parents = [];
+        $topics  = [];
+        $forums  = [];
+
+        foreach ($args as $arg) {
+            if ($arg instanceof Post) {
+                if (! $arg->parent instanceof Topic || ! $arg->parent->parent instanceof Forum) {
+                    throw new RuntimeException('Parents unavailable');
+                }
+                $posts[$arg->id]         = $arg;
+                $parents[$arg->topic_id] = $arg->parent;
+            } elseif ($arg instanceof Topic) {
+                if (! $arg->parent instanceof Forum) {
+                    throw new RuntimeException('Parent unavailable');
+                }
+                $topics[$arg->id] = $arg;
+            } elseif ($arg instanceof Forum) {
+                if (! $this->c->forums->get($arg->id) instanceof Forum) {
+                    throw new RuntimeException('Forum unavailable');
+                }
+                $forums[$arg->id] = $arg;
+            } else {
+                throw new InvalidArgumentException('Expected forum, topic or post');
+            }
+        }
+
+        if (! empty($posts) + ! empty($topics) + ! empty($forums) > 1) {
+            throw new InvalidArgumentException('Expected only forum, topic or post');
+        }
+
+        //???? подписки, опросы, предупреждения, поисковый индекс, метки посещения тем
+
+        $users = [];
+
+        if ($posts) {
+            foreach ($posts as $post) {
+                $users[$post->poster_id] = true;
+            }
+            $users = array_keys($users);
+
+            $vars = [
+                ':posts' => array_keys($posts),
+            ];
+            $sql = 'DELETE FROM ::posts
+                    WHERE id IN (?ai:posts)';
+            $this->c->DB->exec($sql, $vars);
+
+            $topics  = $parents;
+            $parents = [];
+
+            foreach ($topics as $topic) {
+                $parents[$topic->forum_id] = $topic->parent;
+                $this->c->topics->update($topic->calcStat());
+            }
+
+            foreach($parents as $forum) {
+                $this->c->forums->update($forum->calcStat());
+            }
+        } elseif ($topics) {
+            $vars = [
+                ':topics' => array_keys($topics),
+            ];
+            $sql = 'SELECT p.poster_id 
+                    FROM ::posts AS p
+                    WHERE p.topic_id IN (?ai:topics) 
+                    GROUP BY p.poster_id';
+            $users = $this->c->DB->query($sql, $vars)->fetchAll(\PDO::FETCH_COLUMN);
+
+            $sql = 'DELETE FROM ::posts
+                    WHERE topic_id IN (?ai:topics)';
+            $this->c->DB->exec($sql, $vars);
+        } elseif ($forums) {
+            $vars = [
+                ':forums' => array_keys($forums),
+            ];
+            $sql = 'SELECT p.poster_id 
+                    FROM ::posts AS p
+                    INNER JOIN ::topics AS t ON t.id=p.topic_id
+                    WHERE t.forum_id IN (?ai:forums) 
+                    GROUP BY p.poster_id';
+            $users = $this->c->DB->query($sql, $vars)->fetchAll(\PDO::FETCH_COLUMN);
+
+            $sql = 'DELETE FROM ::posts
+                    WHERE topic_id IN (
+                        SELECT id 
+                        FROM ::topics
+                        WHERE forum_id IN (?ai:forums)
+                    )';
+            $this->c->DB->exec($sql, $vars);
+        }
+
+        $this->c->users->updateCountPosts(...$users);
+    }
+}

+ 32 - 0
app/Models/Post/PreviousPost.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace ForkBB\Models\Post;
+
+use ForkBB\Models\Action;
+use ForkBB\Models\Post\Model as Post;
+
+class PreviousPost extends Action
+{
+    /**
+     * Вычисляет номер сообщения перед указанным
+     * 
+     * @param Post $post
+     * 
+     * @return null|int
+     */
+    public function previousPost(Post $post)
+    {
+        $vars = [
+            ':pid' => $post->id,
+            ':tid' => $post->topic_id,
+        ];
+        $sql = 'SELECT p.id
+                FROM ::posts AS p
+                WHERE p.id < ?i:pid AND p.topic_id=?i:tid
+                ORDER BY p.id DESC
+                LIMIT 1';
+        $id = $this->c->DB->query($sql, $vars)->fetchColumn();
+
+        return empty($id) ? null : $id;
+    }
+}

+ 88 - 0
app/Models/Topic/Delete.php

@@ -0,0 +1,88 @@
+<?php
+
+namespace ForkBB\Models\Topic;
+
+use ForkBB\Models\Action;
+use ForkBB\Models\Forum\Model as Forum;
+use ForkBB\Models\Topic\Model as Topic;
+use InvalidArgumentException;
+use RuntimeException;
+
+class Delete extends Action
+{
+    /**
+     * Удаляет тему(ы) 
+     *
+     * @param mixed ...$args
+     *
+     * @throws InvalidArgumentException
+     * @throws RuntimeException
+     */
+    public function delete(...$args)
+    {
+        if (empty($args)) {
+            throw new InvalidArgumentException('No arguments, expected forum or topic');
+        }
+
+        $topics  = [];
+        $parents = [];
+        $forums  = [];
+
+        foreach ($args as $arg) {
+            if ($arg instanceof Topic) {
+                if (! $arg->parent instanceof Forum) {
+                    throw new RuntimeException('Parent unavailable');
+                }
+                $topics[$arg->id]        = $arg;
+                $parents[$arg->forum_id] = $arg->parent;
+            } elseif ($arg instanceof Forum) {
+                if (! $this->c->forums->get($arg->id) instanceof Forum) {
+                    throw new RuntimeException('Forum unavailable');
+                }
+                $forums[$arg->id] = $arg;
+            } else {
+                throw new InvalidArgumentException('Expected forum or topic');
+            }
+        }
+
+        if (! empty($topics) + ! empty($forums) > 1) {
+            throw new InvalidArgumentException('Expected only forum or topic');
+        }
+        
+        $this->c->posts->delete(...$args);
+
+        //???? подписки, опросы, предупреждения, поисковый индекс, метки посещения тем
+
+        if ($topics) {
+            $vars = [
+                ':topics' => array_keys($topics),
+            ];
+            $sql = 'DELETE FROM ::mark_of_topic 
+                    WHERE tid IN (?ai:topics)';
+            $this->c->DB->exec($sql, $vars);
+
+            $sql = 'DELETE FROM ::topics 
+                    WHERE id IN (?ai:topics)';
+            $this->c->DB->exec($sql, $vars);
+
+            foreach($parents as $forum) {
+                $this->c->forums->update($forum->calcStat());
+            }
+        } elseif ($forums) {
+            $vars = [
+                ':forums' => array_keys($forums),
+            ];
+            $sql = 'DELETE FROM ::mark_of_topic 
+                    WHERE tid IN (
+                        SELECT id 
+                        FROM ::topics
+                        WHERE forum_id IN (?ai:forums)
+                    )';
+            $this->c->DB->exec($sql, $vars);
+
+            $sql = 'DELETE FROM ::topics 
+                    WHERE forum_id IN (?ai:forums)';
+            $this->c->DB->exec($sql, $vars);
+        }
+    }
+}

+ 56 - 0
app/Models/User/UpdateCountPosts.php

@@ -0,0 +1,56 @@
+<?php
+
+namespace ForkBB\Models\User;
+
+use ForkBB\Models\Action;
+use ForkBB\Models\User\Model as User;
+use InvalidArgumentException;
+
+class UpdateCountPosts extends Action
+{
+    /**
+     * Обновляет число сообщений пользователя(ей)
+     * 
+     * @param mixed ...$args
+     *
+     * @throws InvalidArgumentException
+     */
+    public function updateCountPosts(...$args)
+    {
+        $ids = [];
+        foreach ($args as $arg) {
+            if ($arg instanceof User) {
+                $ids[$arg->id] = true;
+            } elseif (is_int($arg) && $arg > 0) {
+                $ids[$arg] = true;
+            } else {
+                throw new InvalidArgumentException('Expected user or positive integer id');
+            }
+        }
+        // сообщения гостя не считаем
+        unset($ids[1]);
+
+        if (empty($ids)) {
+            $where = 'u.id != 1';
+            $vars  = [];
+        } else {
+            $where = 'u.id IN (?ai:ids)';
+            $vars  = [
+                ':ids' => array_keys($ids),
+            ];
+        }
+
+        $sql = 'UPDATE ::users AS u
+                SET u.num_posts = (
+                    SELECT COUNT(p.id)
+                    FROM ::posts AS p
+                    INNER JOIN ::topics AS t ON t.id=p.topic_id
+                    INNER JOIN ::forums AS f ON f.id=t.forum_id
+                    WHERE p.poster_id=u.id AND f.no_sum_mess=0
+                    GROUP BY p.poster_id
+                )
+                WHERE ' . $where;
+
+        $this->c->DB->exec($sql, $vars);
+    }
+}