Ru-Board.club
← Вернуться в раздел «Ikonboard v.3»

» Фиксация первого сообщения в многостраничных топиках

Автор: DStream
Дата сообщения: 23.01.2004 01:15
Умышленно пишу отдельной темой, так как это пока еще сырой вариант. Проверен на локалхосте и несколько минут крутится на живом форуме. В ходе написания было несколько идей разных путей реализации. Хотелось бы их обсудить и уже финальный вариант внести в БД модификаций и добавлений.

Итак:
Название: Фиксация первого сообщения в многостраничных топиках

Описание: Позволяет закрепить первое сообщение в длинном многостраничном топике для того, чтобы оно отображалось на каждой странице обсуждения.

Применение: Например подготовка к какой-либо тусовке, где автор (инициатор) топика собирает список и корректирует место, время и дату сбора.

Версия: iB 3.1.2a mySQL (Вероятнее всего применим и к iB 3.1.1 и должен работать с DBM)

Изменяемые файлы:
Sources/Topic.pm
Sources/Moderate.pm
Skin/{your skin}/TopicView.pm
Skin/{your skin}/Styles.pm
Languages/{your lang}/TopicWords.pm
Languages/{your lang}/ModerateWords.pm
Database/config/forum_posts.cfg
ib_forum_posts

Автор: DStream D-Stream@mail.ru

1. Сохраняем изменяемые файлы (backup) и таблицу ib_forum_posts
2. Добавляем в таблицу ib_forum_posts еще одну колонку PINNED_FIRST_POST тип: tinyint(1), allow null. Это можно сделать через web-фейс к mySQL или в виде запроса
Цитата:
alter table ib_forum_posts
add column PINNED_FIRST_POST tinyint(1) null after ATTACH_TYPE,
type=MyISAM;

3. В файле Database/config/forum_posts.cfg ищем
Цитата:
%{ $COLS } = ( POST_ID => [0, 'update', 10, 1],
AUTHOR => [1, 'string', 32 ],
ENABLE_SIG => [2, 'num' , 1 ],
ENABLE_EMO => [3, 'num' , 1 ],
IP_ADDR => [4, 'string', 16, 1],
POST_DATE => [5, 'num' , 10, 1],
POST_ICON => [6, 'num' , 2 ],
POST => [7, 'text' , -1 ],
AUTHOR_TYPE => [8, 'num' , 1 ],
QUEUED => [9, 'num' , 1 ],
TOPIC_ID => [10,'num' , 10, 1],
FORUM_ID => [11,'num' , 5 , 1],
ATTACH_ID => [12,'string', 64, ],
ATTACH_HITS => [13,'num' , 5 ],
ATTACH_TYPE => [14,'string', 128 ],

и добавляем строку

Цитата:
PINNED_FIRST_POST => [2, 'num' , 1 ],

4. В файле Languages/{your lang}/TopicWords.pm
ищем
Цитата:
PIN_TOPIC =>
и добавляем после этой строки
Цитата:
'PIN_FIRST_POST' => q!Закрепить первое сообщение в теме!,
'UNPIN_FIRST_POST' => q!Освободить первое сообщение в теме!,

5. В файле Languages/{your lang}/ModerateWords.pm
ищем
Цитата:
p_moved =>
и ниже добавляем
Цитата:
'p_pin_first_post' => q!Первое сообщение закреплено!,
'p_unpin_first_post' => q!Первое сообщение освобождено!,


6. В файле Skin/{your skin}/Styles.pm ищем
Цитата:
'P_WEBSITE' => qq!<img src="$iB::INFO->{'IMAGES_URL'}/Skin/Default/images/pb_website.gif" border="0" alt="WEB">!,
'P_YIM' => qq!<img src="$iB::INFO->{'IMAGES_URL'}/Skin/Default/images/pb_yahoo.gif" border="0" alt="YIM">!,
и ниже добавляем
Цитата:
'P_PIN_FIRST' => qq!<img src="$iB::INFO->{'IMAGES_URL'}/Skin/Default/images/f_pin.gif" border="0" alt="Прикрепленное первое сообщение">!,
не уверен, что f_pin.gif есть у всех, но речь идет о маленькой иконке типа pin topic и т.п.
7. В файле Sources/Moderate.pm:
ищем
Цитата:
my %Mode = ( '00' => \&CloseForm,
'01' => \&OpenForm,
'02' => \&MoveForm,
'03' => \&DeleteForm,
и добавляем в конце
Цитата:
'21' => \&PinFirstPost,
'22' => \&UNPinFirstPost

ищем
Цитата:
sub UNPinTopic {
my ($obj, $db) = @_;
$obj->{'MODE'} = 'UNPIN_TOPIC';
$obj->CheckAuthorisation($db);
$std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'moderate_no_permission') unless $obj->{'PASSED'} == 1;
$db->update( TABLE => 'forum_topics',
KEY => $obj->{'.topic_id'},
ID => $obj->{'.forum_id'},
VALUES => { PIN_STATE => 0 }
) || die $db->{'error'};
$output->redirect_screen(TEXT => $Moderate::lang->{p_unpinned}, URL => "act=ST;f=$obj->{'.forum_id'};t=$obj->{'.topic_id'}");
}
и добавляем после
Цитата:
sub PinFirstPost {
my ($obj, $db) = @_;
$obj->{'MODE'} = 'PIN_FIRST_POST';
$obj->CheckAuthorisation($db);
$std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'moderate_no_permission') unless $obj->{'PASSED'} == 1;
my $tmpq = $db->query( TABLE => 'forum_posts',
DBID => 'f'.$obj->{'.forum_id'},
ID => $obj->{'.topic_id'},
WHERE => "TOPIC_ID == '$obj->{'.topic_id'}' and QUEUED != '1'",
RANGE => '0 to 1',
SORT_KEY => 'POST_DATE',
);
my $pin_post = @{$tmpq}[0];
my $pin_post_id = $pin_post->{'POST_ID'};

$db->update( TABLE => 'forum_posts',
WHERE => "POST_ID = $pin_post_id",
VALUES => { PINNED_FIRST_POST => '1' }
) || die "T:".$db->{'error'};
$output->redirect_screen(TEXT => $Moderate::lang->{p_pin_first_post}, URL => "act=ST;f=$obj->{'.forum_id'};t=$obj->{'.topic_id'}");
}


sub UNPinFirstPost {
my ($obj, $db) = @_;
$obj->{'MODE'} = 'UNPIN_FIRST_POST';
$obj->CheckAuthorisation($db);
$std->Error( DB => $db, LEVEL=>'1',MESSAGE=>'moderate_no_permission') unless $obj->{'PASSED'} == 1;
my $tmpq = $db->query( TABLE => 'forum_posts',
DBID => 'f'.$obj->{'.forum_id'},
ID => $obj->{'.topic_id'},
WHERE => "TOPIC_ID == '$obj->{'.topic_id'}' and QUEUED != '1'",
RANGE => '0 to 1',
SORT_KEY => 'POST_DATE',
);
my $pin_post = @{$tmpq}[0];
my $pin_post_id = $pin_post->{'POST_ID'};

$db->update( TABLE => 'forum_posts',
WHERE => "POST_ID = $pin_post_id",
VALUES => { PINNED_FIRST_POST => '0' }
) || die "T:".$db->{'error'};
$output->redirect_screen(TEXT => $Moderate::lang->{p_unpin_first_post}, URL => "act=ST;f=$obj->{'.forum_id'};t=$obj->{'.topic_id'}");
}

Продолжение завтра...
Автор: DStream
Дата сообщения: 25.01.2004 15:18
Прошу прощения за задержку со второй частью...

8. В файле Source/Topic.pm ищем

Цитата:
#+---------------------------------------------------------
# Grab the posts to show.
#+---------------------------------------------------------

my $total_posts = $db->query( TABLE => 'forum_posts',
DBID => 'f'.$obj->{'.forum_id'},
ID => $obj->{'.topic_id'},
WHERE => "TOPIC_ID == '$obj->{'.topic_id'}' and QUEUED != '1'",
RANGE => $First.' to '.($iB::INFO->{'DISPLAY_MAX_POSTS'} + ($First - 1)),
SORT_KEY => 'POST_DATE',
SORT_BY => $sort_by
);

и добавляем

Цитата:
my $pin_flag; # if true - pin first post POST_ID
if (1) { # check flag of PINNED_FIRST_POST
my $pinned_post = $db->query( TABLE => 'forum_posts',
DBID => 'f'.$obj->{'.forum_id'},
ID => $obj->{'.topic_id'},
WHERE => "TOPIC_ID == '$obj->{'.topic_id'}' and QUEUED != '1'",
RANGE => '0 to 1',
SORT_KEY => 'POST_DATE',
SORT_BY => $sort_by
);
my $tmp = @{$pinned_post}[0];
$pin_flag = $tmp->{'POST_ID'} if $tmp->{'PINNED_FIRST_POST'};
if ($pin_flag) {
push @{$pinned_post},@{$total_posts};
$total_posts=$pinned_post;
}
}


ищем
Цитата:
$Print .= TopicView::RenderRow( { POST => $Row, POSTER => $obj->{'POSTER'} } );
$obj->{'POSTER'} = undef;
}

и добавляем перед
Цитата:
$Row->{'PIN_FLAG'} = "$iB::SKIN->{'P_PIN_FIRST'}" if ($Row->{'POST_ID'} eq $pin_flag);


ищем
Цитата:
for my $key (qw[MOVE_TOPIC CLOSE_TOPIC OPEN_TOPIC DELETE_TOPIC EDIT_TOPIC PIN_TOPIC GLOBAL_PIN UNPIN_TOPIC RECOUNT ADD_TOPIC_WATCH REMOVE_TOPIC_WATCH]) {
и заменяем на
Цитата:
for my $key (qw[MOVE_TOPIC CLOSE_TOPIC OPEN_TOPIC DELETE_TOPIC EDIT_TOPIC PIN_TOPIC GLOBAL_PIN PIN_FIRST_POST UNPIN_FIRST_POST UNPIN_TOPIC RECOUNT ADD_TOPIC_WATCH REMOVE_TOPIC_WATCH]) {


ищем
Цитата:
my $action = { 'CLOSE_TOPIC' => '00',
'OPEN_TOPIC' => '01',
'MOVE_TOPIC' => '02',
'DELETE_TOPIC' => '03',
'EDIT_TOPIC' => '05',
'PIN_TOPIC' => 15,
'UNPIN_TOPIC' => 16,
'RECOUNT' => 17,
и в конце добавляем
Цитата:
'PIN_FIRST_POST' =>21,
'UNPIN_FIRST_POST' =>22,


ищем
Цитата:
elsif ($key eq 'DELETE_TOPIC') {
$obj->{'.can_do'} .= $obj->_append($key) if ($iB::MEMBER_GROUP->{'DELETE_OWN_TOPICS'});
}
и добавляем
Цитата:
elsif ($key eq 'PIN_FIRST_POST' or $key eq 'UNPIN_FIRST_POST') {
if ($iB::MEMBER_GROUP->{'IS_SUPMOD'} or $obj->{'moderator'}->{ $key }) {
$obj->{'.can_do'} .= $obj->_append($key);
}
}


9. В файле Skin/{your skin}/TopicView.pm:
ищем
Цитата:
<td valign='middle' align='left'>$data->{'POST'}->{'POST_ICON'}</td>
и перед ней добавляем
Цитата:
<td valign='middle' align='left'>$data->{'POST'}->{'PIN_FLAG'}</td>


Собственно все.
Наиболее удобное добавление хака - скоприровать текущие файлы, поправить их и залить обратно на хостинг.

Из замеченных недостатков: иногда почему-то прикрепляется не первое сообщение. Как замечено это происходит в случае незарегистрированного автора топика.

Вариации: можно было бы сделать управление pin/unpin в виде триггера.
Возможно неплохо бы смотрелся вариант с разположением pin/unpin в самом постинге и как следствие возможность закрепления нескольких сообщений.
Автор: derphy
Дата сообщения: 05.10.2005 17:11
Сэры, существуют следующие проблемы в связи с этим хаком:
1) Посты могут прикреплять только админы.
2) Вместе с первым постом цепляется и второй.

Подскажите пожалуйста, механизм решения этих проблем.
Автор: DStream
Дата сообщения: 06.10.2005 08:31
derphy, полная сыромятина, поэтому как в инструкции по жигулям - "по месту доработать напильником"

1. помнится мне, что просто линки показываются только админам, что поправляется.
2. надо поиграться с RANGE => '0 to 1',

Автор: derphy
Дата сообщения: 07.10.2005 19:29
ЭЭээ Можно ли поподробнее описать порядок действий?
А то просто с движком на и с перлом вообще столкнулся впервые
Автор: DStream
Дата сообщения: 10.10.2005 08:50
derphy, сорри, но если бы было время и желание - то давно бы сам доработал.
Кстати не понимаю выбора движка на перле если не знаешь перл...
Автор: derphy
Дата сообщения: 10.10.2005 09:03
В том-то все и дело, что не я его выбирал, а человек, который раньше им занимался теперь делать этого не может... надо помочь.
Автор: DStream
Дата сообщения: 16.10.2005 08:45

Цитата:
В том-то все и дело, что не я его выбирал, а человек, который раньше им занимался теперь делать этого не может... надо помочь.
думаю стоит почитать книжки по перлу и поковырять сорцы. Хуже от этого не будет однозначно. Знания еще никому не вредили.

Страницы: 1

Предыдущая тема: Нужен админ форуму


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.