Browse Source

Add a link to the breadcrumbs that returns the user to the list of topics to the topic they left

Visman 2 years ago
parent
commit
2c4a9e407f

+ 9 - 1
app/Controllers/Routing.php

@@ -295,14 +295,22 @@ class Routing
                     'SetNewEmail'
                 );
             }
-            // пометка разделов прочитанными
+
             if (! $user->isGuest) {
+                // пометка разделов прочитанными
                 $r->add(
                     $r::GET,
                     '/forum/{id|i:\d+}/markread/{token}',
                     'Misc:markread',
                     'MarkRead'
                 );
+                // скролирование до топика
+                $r->add(
+                    $r::GET,
+                    '/forum/scroll/topic/{tid|i:[1-9]\d*}',
+                    'Forum:scrollToTopic',
+                    'ForumScrollToTopic'
+                );
             }
 
             // разделы

+ 36 - 6
app/Models/Forum/Forum.php

@@ -417,6 +417,35 @@ class Forum extends DataModel
             return [];
         }
 
+        $this->createIdsList(
+            $this->c->user->disp_topics,
+            ($this->page - 1) * $this->c->user->disp_topics
+        );
+
+        return empty($this->idsList) ? [] : $this->c->topics->view($this);
+    }
+
+    /**
+     * Вычисляет страницу раздела на которой находится данная тема
+     */
+    public function calcPage(int $tid): void
+    {
+        $this->createIdsList();
+
+        $arr = \array_flip($this->idsList);
+
+        if (isset($arr[$tid])) {
+            $this->page = (int) \ceil(($arr[$tid] + 1) / $this->c->user->disp_topics);
+        } else {
+            $this->page = null;
+        }
+    }
+
+    /**
+     * Создает список id тем раздела
+     */
+    protected function createIdsList(int $rows = null, int $offset = null): void
+    {
         switch ($this->sort_by) {
             case 1:
                 $sortBy = 't.posted DESC';
@@ -440,18 +469,19 @@ class Forum extends DataModel
 
         $vars = [
             ':fid'    => $this->id,
-            ':offset' => ($this->page - 1) * $this->c->user->disp_topics,
-            ':rows'   => $this->c->user->disp_topics,
+            ':offset' => $offset,
+            ':rows'   => $rows,
         ];
         $query = "SELECT t.id
             FROM ::topics AS t
             WHERE t.forum_id=?i:fid
-            ORDER BY t.sticky DESC, {$sortBy}, t.id DESC
-            LIMIT ?i:rows OFFSET ?i:offset";
+            ORDER BY t.sticky DESC, {$sortBy}, t.id DESC";
 
-        $this->idsList = $this->c->DB->query($query, $vars)->fetchAll(PDO::FETCH_COLUMN);
+        if (isset($rows, $offset)) {
+            $query .= ' LIMIT ?i:rows OFFSET ?i:offset';
+        }
 
-        return empty($this->idsList) ? [] : $this->c->topics->view($this);
+        $this->idsList = $this->c->DB->query($query, $vars)->fetchAll(PDO::FETCH_COLUMN);
     }
 
     /**

+ 4 - 0
app/Models/Page.php

@@ -528,6 +528,10 @@ abstract class Page extends Model
                         $this->titles = ['Page %s', $crumb->page];
                     }
 
+                    if ($crumb->linkCrumbExt) {
+                        $result[] = [$crumb->linkCrumbExt, '#', null];
+                    }
+
                     $crumb = $crumb->parent;
                 } while (
                     $crumb instanceof Model

+ 32 - 1
app/Models/Pages/Forum.php

@@ -12,6 +12,7 @@ namespace ForkBB\Models\Pages;
 
 use ForkBB\Models\Page;
 use ForkBB\Models\Forum\Forum as ForumModel;
+use ForkBB\Models\Topic\Topic;
 use function \ForkBB\__;
 
 class Forum extends Page
@@ -19,7 +20,7 @@ class Forum extends Page
     /**
      * Подготовка данных для шаблона
      */
-    public function view(array $args): Page
+    public function view(array $args, string $method): Page
     {
         $this->c->Lang->load('forum');
         $this->c->Lang->load('subforums');
@@ -126,4 +127,34 @@ class Forum extends Page
 
         return $form;
     }
+
+    /**
+     * Подготовка данных для шаблона
+     */
+    public function scrollToTopic(array $args, string $method): Page
+    {
+        $topic = $this->c->topics->load($args['tid']);
+
+        if (! $topic instanceof Topic) {
+            return $this->c->Message->message('Bad request');
+        }
+
+        $forum = $topic->parent;
+
+        $forum->calcPage($args['tid']);
+
+        if (null === $forum->page) {
+            return $this->c->Message->message('Bad request');
+        }
+
+        return $this->c->Redirect->page(
+            'Forum',
+            [
+                'id'   => $forum->id,
+                'name' => $forum->forum_name,
+                'page' => $forum->page,
+                '#'    => "topic-{$topic->id}",
+            ]
+        );
+    }
 }

+ 17 - 0
app/Models/Topic/Topic.php

@@ -193,6 +193,23 @@ class Topic extends DataModel
         );
     }
 
+    /**
+     * Дополнительная ссылка для хлебных крошек
+     */
+    protected function getlinkCrumbExt(): ?string
+    {
+        if ($this->c->user->isGuest) {
+            return null;
+        } else {
+            return $this->c->Router->link(
+                'ForumScrollToTopic',
+                [
+                    'tid'  => $this->id,
+                ]
+            );
+        }
+    }
+
     /**
      * Статус наличия новых сообщений в теме
      */

+ 1 - 0
public/robots.txt

@@ -6,3 +6,4 @@ Disallow: /reg
 Disallow: /search
 Disallow: /userlist
 Disallow: /post
+Disallow: /forum/scroll