From e520a1139a35b2e8f30407dcee80ad363f0e3b76 Mon Sep 17 00:00:00 2001 From: Victor Wagner Date: Mon, 24 Mar 2008 15:32:04 +0000 Subject: [PATCH] Implemented, but untested reply function without text to link conversion and topic paging. --- forum/forum | 215 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 189 insertions(+), 26 deletions(-) diff --git a/forum/forum b/forum/forum index 59bc266..989c5bc 100755 --- a/forum/forum +++ b/forum/forum @@ -770,37 +770,152 @@ sub reply { # # Находим файл дискуссии, в который надо поместить реплику # + my ($tree,$lockfd)=gettree($ENV{'PATH_TRANSLATED'}); + my $messagetpl = $tree->look_down(class=>"message"); + if (!$messagetpl) { + show_error($forum,"Шаблон темы не содержит элемента с классом + message"); + exit; + } + # + # Генерируем идентификатор записи. # - # Сохраняем приаттаченную картинку, если есть. + my $id = get_uid($forum); + + # - - # Генерируем идентификатор записи. + # Сохраняем приаттаченные картинки, если есть. # - + my $dir = $ENV{PATH_TRANSLATED}; + $dir=~ s/[^\/]+$// if (-f $dir); + my %attached; + for (my $i=1;defined $cgi->param("image$i"); $i++) { + my $userpath=$cgi->param("image$i"); + my $filename=lc($1) if $userpath =~ /([^\/\\]+)$/; + attached{$filename} = $id."_".$filename; + my $in = $cgi->upload("image$i"); + my $out; + open $out,">$dir/$attached{$filename}"; + binmode $out,":bytes"; + local $_=undef; + my $data = <$in>; + print $out $data; + close $in; + close $out; + } + # # Преобразуем текст записи в html и чистим его # - my $txtree = undef; - if ($cgi->param("format") eq "bbcode") { - - } elsif ($cgi->param("format") eq "text") { - my $text = $cgi->escapeHTML($cgi->param("text")); - $text=~s/\r?\n\r?\n/

/; - $text=~s/\n/
/; - $txtree = - HTML::TreeBuilder->new_from_content("

$text
"); - } else { # Default - html - $txtree = - HTML::TreeBuilder->new_from_content("
".$cgi->param("text")."
"); - for my $badtag - ("script","style","head","html","object","embed","iframe","frameset","frame", - ($forum->{forbid_tags}?split(/\s*,\s*/,$forum->{forbid_tags}):())) { - for my $element ($txtree->find_by_tag_name($badtag)) { - $element->delete() if defined $element; - } + my $txtree = input2tree($cgi,$forum,"text"); + # + # Находим в тексте URL на приаттаченные картинки и меняем на те + # имена, под которыми мы их сохранили. + # + for my $image ($txtree->find_by_tag_name("img")) { + my $file; + if ( exists $attached{$file=lc($image->attr("src"))}) { + $image->attr("src" => $attached{$file}); + my ($width,$height) = imgsize($dir ."/".$attached{$file}); + $image->attr("width" =>$width); + $image->attr("height" => $height); } } + # + # Копируем элемент с классом message + # + my $newmsg = $messagetpl->clone; + my $parent = $messagetpl->parent; + $parent->push_content($newmsg); + # + # Подставляем данные сообщения + # + $newmsg->attr("id"=>$id); + if (my $subj=$newmsg->look_down("class"=>"subject") && + $cgi->param("subject")) { + $subj->delete_content; + $subj->push_content($cgi->param("subject")); + } + my $textnode=$newmsg->look_down("class"=>"mtext"); + if (!$textnode) { + show_error($forum,"В шаблоне реплики нет места для текста"); + } + $textnode->delete_content(); + $textnode->push_content($txtree); + if ($forum->{authenticated}{signature}) { + $textnode->push_content(new HTML::Element("br"),"--", + new HTML::Element("br"),str2tree($forum->{authenticated}{signature})); + } + substitute_user_info($newmsg,$forum); + # + # Подставляем данные в форму msginfo + # + my $editform=$newmsg->look_down(_tag=>"form","class"=>"msginfo"); + if ($editform) { + my $idfield = $editform->look_down(_tag=>"input","name"=>"id"); + if (!$idfield) { + show_error($forum,"В форме управления сообщением нет поля + id"); + } + $idfield->attr("value" => $id); + my $authorfield = $editform->look_down(_tag=>"input","name"=>"author"); + if (!$authorfield) { + show_error($forum,"В форме управления сообщением нет поля + id"); + } + $authorfield->attr("value"=>$forum->{authenticated}{user}); + } + # Подставляем mdate + my $date = $newmsg->look_down("class"=>"mdate"); + if ($date) { + $date->delete_content; + $date->push_content(strftime("%d.%m.%Y %H:%M",localtime())); + + } + # Подставляем mreply + my $reply_link = $newmsg->look_down(_tag=>"a","class"=>"mreply"); + $reply_link->attr("href"=> $cgi->url(-absolute=>1,-path_info=>1). + "?reply=1&id=$id") if ($reply_link); + # Подставляем manchor + my $anchor = $newmsg->look_down(_tag=>"a","class"=>"manchor"); + if (! $anchor) { + show_error($forum,"В шаблоне сообщения отсутствует якорь для + ссылок на него"); + exit; + } + $anchor->attr(href=>undef); + $anchor->attr(name=>"#$id"); + # подставляем mlink + my $link = $newmsg->look_down(_tag=>"a","class"=>"mlink"); + $link->attr(href=>$cgi->path_info."#id"); + # подставляем mparent + my $parent_id=$cgi->param("id"); + my $parent_link=$newmsg->lookdown(_tag => "a",class=>"mparent"); + if ($parent_link) { + if ($parent_id) { + $parent_link->attr("href"=>$cgi->path_info."#$parent_id"); + } else { + # Если parent_id отсутствует, т.е. это начало нового треда + # просто делаем ссылку невидимой. + $parent_link->delete_content(); + } + } + + # + # Проверяем видимость списка сообщений + # + my $msglist = $tree->look_down("class"=>"messagelist"); + if ($msglist) { + my $style = $msglist->attr("style"); + $msglist->attr("style",$style) if $style =~ s/display: none;//; + } + # + # Делаем Уфф и сохраняем то, что получилось + # + savetree($ENV{PATH_TRANSLATED},$tree,$lockfd); + forum_redirect($cgi,$forum); + } # # читает файлы прав доступа в дереве форума, и возвращает @@ -858,7 +973,7 @@ sub gettree { my $f; open $f,"<",$filename or return undef; flock $f, LOCK_EX; - my $tree = HTML::TreeBuider->new_from_file($f); + my $tree = HTML::TreeBuilder->new_from_file($f); return ($tree,$f); } # @@ -895,9 +1010,9 @@ sub get_uid { close $f; return sprintf ("%08s",$id); } -# -# ----------------- OpenID registration ----------------------------- -# +# -------------------------------------------------------------------- +# OpenID registration +# ------------------------------------------------------------------- sub create_openid_consumer { my ($cgi,$forum) = @_; return Net::OpenID::Consumer ->new( @@ -981,3 +1096,51 @@ sub openid_verify { exit; } } +#----------------------------------------------------------------- +# Обработка форматированных текстовых полей +#----------------------------------------------------------------- + +sub input2tree { + my ($cgi,$forum,$field_name) = @_; + my $format = $cgi->param($field_name."_format"); + my $text = $cgi->param($field_name); + + if ($format eq "bbcode") { + my $parser = HTML::BBReverse->new(); + $text="
".$parser->parse($text)."
"; + + } elsif ($format eq "text") { + $text=~s/\r?\n\r?\n/<\/p>

/; + $text=~s/\r?\n/
/; + $text = "

".$text."

"; + } else { + $text="
".$text."
"; + } + my $txtree = str2tree($text); + for my $badtag + ("script","style","head","html","object","embed","iframe","frameset","frame", + ($forum->{forbid_tags}?split(/\s*,\s*/,$forum->{forbid_tags}):())) { + for my $element ($txtree->find_by_tag_name($badtag)) { + $element->delete() if defined $element; + } + } + # Проверяем на наличие URL-ок не оформленных ссылками. + return $txtree; +} + + + +sub str2tree { + my ($data)=@_; + my $tree = HTML::TreeBuilder->new(); + # Set parser options here + $tree->parse($data); + $tree->eof; + return $tree; + +} + +sub tree2str { + my ($tree)=@_; + return $tree->as_HTML("<>&"); +} -- 2.39.2