From: Victor Wagner <vitus@wagner.pp.ru>
Date: Tue, 25 Mar 2008 10:00:40 +0000 (+0000)
Subject: Отрефакторена подстановка атрибутов в дерево. Поправлено распознавание
X-Git-Url: http://wagner.pp.ru/gitweb/?a=commitdiff_plain;h=ef113e7b0771c7642d2b72668f0678129a7ddd1a;p=oss%2Fstilllife.git

Отрефакторена подстановка атрибутов в дерево. Поправлено распознавание
openid-юзеров при подстановке ссылки на юзера.
Добавлен отладочный скрипт (командно строчный) для дампа базы юзеров и
сессий.
---

diff --git a/forum/dumpbase b/forum/dumpbase
new file mode 100644
index 0000000..410ae3c
--- /dev/null
+++ b/forum/dumpbase
@@ -0,0 +1,17 @@
+#!/usr/bin/perl
+
+use Data::Dumper;
+use Storable qw(thaw);
+
+dbmopen %x,$ARGV[0],0644;
+
+while (my ($key,$val) = each %x) {
+	my $data;
+	eval {
+		$data = Dumper(thaw($val));	
+	}; 	
+	if ($@) {
+		$data = $val;
+	}	
+	print $key, " => ",$data,"\n";
+}	
diff --git a/forum/forum b/forum/forum
index 6b0c9c1..e7cbc92 100755
--- a/forum/forum
+++ b/forum/forum
@@ -424,39 +424,27 @@ my %userinfo = %{$forum->{"authenticated"}};
 #
 # Специально обрабатываем поля user (должна быть ссылка) и avatar  
 # (должен быть img).
-my @userlink = $tree->look_down("_tag"=>"a","class"=>"author");
-if (@userlink) {
 	my $userpage;
-	if ($userinfo{"user"}=~/^http:/) {
-		$userpage = $userinfo{"user"};
+	if ($userinfo{"openiduser"}) {
+		$userpage = "http://".$userinfo{"user"};
 	} else {
 		$userpage =
 		$cgi->url(-absolute=>1).$forum->{"userurl"}."/".$cgi->escape($userinfo{"user"});
 	}	
-	for my $element (@userlink) {
-		$element->attr(href=>$userpage);
-		$element->delete_content();
-		$element->push_content($userinfo{"user"});
-	}
-}	
-delete $userinfo{"userpage"};
-delete $userinfo{"user"};
-my $avatar = $tree->look_down("_tag"=>"img","class"=>"avatar");
-if ($avatar) {
-	$avatar->attr(src=>$userinfo{"avatar"});
-}
-delete $userinfo{"avatar"};
+	substinfo($tree,["_tag"=>"a","class"=>"author"],
+	 href=>$userpage,_content=>$userinfo{"user"});
+	delete $userinfo{"user"};
+	substinfo($tree,["_tag"=>"img","class"=>"avatar"],
+	src=>$userinfo{"avatar"}||$forum->{templatesurl}."/1x1.gif");
+	delete $userinfo{"avatar"};
 
-while (my ($field,$value)=each %userinfo) {
-	my $element = $tree->look_down("class","a".$field);
-	if ($element) {
-	 	$element->delete_content();
-		# 
-		# FixME - allow HTML in author attributes
-		$element->push_content($value);
+	for my $element ( $tree->look_down("class",qr/^ap-/)) {
+		my $field=$1 if $element->attr("class")=~/^ap-(.*)$/;	
+		$element->delete_content();
+		$element->push_content(str2tree($userinfo{$field})) 
+				if $userinfo{$field};
 	}
 
-}
 
 }
 #
@@ -837,11 +825,7 @@ sub reply {
 	# Подставляем данные сообщения 
 	#
 	$newmsg->attr("id"=>$id);
-	if ((my $subj=$newmsg->look_down("class"=>"subject")) &&
-		$cgi->param("subject")) {
-		$subj->delete_content;
-		$subj->push_content($cgi->param("subject"));
-	}
+	substinfo($newmsg,[class=>"subject"],_content=>$cgi->param("subject"));
 	my $textnode=$newmsg->look_down("class"=>"mtext");
 	if (!$textnode) {
 		show_error($forum,"В шаблоне реплики нет места для текста"); 
@@ -858,52 +842,33 @@ sub reply {
 	#
 	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) {
+		substinfo($editform,[_tag=>"input",name=>"id"],value=>$id) ||
+			show_error($forum,"В форме управления сообщением нет поля id");
+		substinfo($editform,[_tag=>"input",name=>"author"],value=>
+			$forum->{authenticated}{user}) ||
 			show_error($forum,"В форме управления сообщением нет поля author");
-		}
-		$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()));
-
-	}	
+	substinfo($newmsg,["class"=>"mdate"],
+		_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);
+	substinfo($newmsg,[_tag=>"a","class"=>"mreply"],"href" =>
+	 $cgi->url(-absolute=>1,-path_info=>1)."?reply=1&id=$id");
 	# Подставляем manchor
-	my $anchor = $newmsg->look_down(_tag=>"a","class"=>"manchor");
-	if (! $anchor) {
-		show_error($forum,"В шаблоне сообщения отсутствует якорь для
-		ссылок на него");
-		exit;
-	}	
-	$anchor->attr(href=>undef);
-	$anchor->attr(name=>"#$id");
+	substinfo($newmsg,[_tag=>"a","class"=>"manchor"],
+		"name"=>"#$id","href"=>undef) or
+		show_error($forum,"В шаблоне сообщения отсутствует якорь для ссылок на него");
 	# подставляем mlink
-	my $link = $newmsg->look_down(_tag=>"a","class"=>"mlink");
-	$link->attr(href=>$cgi->path_info."#id") if $link; 
+	substinfo($newmsg,[_tag=>"a","class"=>"mlink"],
+		href=>$cgi->path_info."#id");
 	# подставляем mparent
 	my $parent_id=$cgi->param("id");
-	my $parent_link=$newmsg->look_down(_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();
-		}
+	if ($parent_id) {
+		substinfo($newmsg,[_tag => "a",class=>"mparent"], 
+			"href"=>$cgi->path_info."#$parent_id");
+	} else {
+		substinfo($newmsg,[_tag => "a",class=>"mparent"], 
+			"_content"=>"");
 	}	
 
 	#
@@ -1150,3 +1115,42 @@ sub tree2str {
 	my ($tree)=@_;
 	return $tree->as_HTML("<>&");
 }
+
+#------------------------------------------------------------------------
+# Подстановка в дереве
+#------------------------------------------------------------------------
+
+#
+# Найти все элементы, удоволетворяющие заданному критерию и подставить в
+# них указанные атрибуты
+# 
+# Параметры 1. Дерево (класса HTML::Element)
+# 2. Запрос - ссылка на список вида атрибут=>значение. 
+#    Этот список будет непосредственно передан в
+#    HTML::Element::look_down
+# 3. Далее пары имя-атрибута, значение. Если вместо имени атрибута
+#    использовать слово _content, заменено будет содержимое элемента.
+#    Значение для _content - ссылка на HTML::Element. Если там строка,
+#    она будет вставлена как одиночный текстовый узел.
+# 4. Возвращает число выполненных подстановок (0, если искомых элементов   
+#   не найдено.
+#
+sub substinfo {
+	my ($tree,$query,@attrs) = @_;
+	my $count;
+	foreach my $element ($tree->look_down(@$query)) {
+		$count ++;
+		while (@attrs) {
+			my $attr = shift @attrs;
+			my $value = shift @attrs;
+			if ($attr eq "_content") {
+				$element->delete_content;
+				$element->push_content($value);
+			} else {	
+				$element->attr($attr,$value);
+			}	
+		}	
+	}
+	return $count;	
+}
+