表紙 | 新規 | 一覧 | RSS | 検索 | 閲覧履歴 | 作成履歴 | 更新履歴

do_write関数 - YukiWikiベースのPonyWikiのソースを読んでみる その07

差分表示


[[YukiWikiベースのPonyWikiのソースを読んでみる]] その07

自動リンク・自動アンリンク・ページ作成・ページ削除・ページ更新を行っている関数。ちょっと大きすぎるのでもっと綺麗に書き直したい。


処理の流れとしては以下の通りです。

- 凍結ページかどうかの区別
- 編集可能ページかどうかの区別
- 部分編集の場合は、他の部分とマージ
- 自動リンクの処理
-- 既存ページ名でループを回し、書き込む内容(&verb($form{mymsg}))に合致する個所があれば&verb([[]])でくくる。
-- 既存ページ名でループを回し、書き込む内容(&verb($form{mymsg}))に合致する個所があれば&verb()でくくる。
--- 既存ページ名は、ページ名の長さでソートする。第二キーは文字コード順。
-- プラグインの中まで&verb([[]])でくくっていれば&verb([[]])を消す
-- プラグインの中まで&verb()でくくっていれば&verb()を消す
- ページ名が入れ子になっているような場合対策として消し込む
-- 「&verb(WorldWideWeb)」というページと「&verb(Wide)」というページがあった場合に、&verb([[[[WorldWide]]Web]])となってしまう事への対策
-- 「&verb(WorldWideWeb)」というページと「&verb(Wide)」というページがあった場合に、&verb(WorldWideWeb)となってしまう事への対策
- 既存ページへの自動リンク
-- 新規作成の場合は、既存ページに新規作成ページ名が存在すれば自動的にリンクを作成する
-- ここでもプラグインと入れ子対策を行っている
- 検索用インデックスの更新
- 衝突のチェック
- 差分作成
- &verb(RecentCreates)の更新
-- 新規作成時のみ
- データ更新
-- 内容の更新
-- 衝突検出用の最終書き込み時刻更新
- &verb(RecentChanges)の更新
-- チェックが入っていた場合のみ
- メッセージ類の表示

以下削除時の動作。差分作成までは同じです。&br()
&verb(if ($form{mymsg}) {)で内容が空であれば削除として動作します。
- 検索用インデックスの更新
- &verb(RecentCreates)の更新
- %databseと%infobaseからデータを削除
- &verb(RecentChanges)の更新
- 既存ページ存在する、削除したページへのリンクを消していく
- メッセージ類の表示

---(
sub do_write {
    if (&frozen_reject()) {
        return;
    }
	my $mtime;

    if (not &is_editable($form{mypage})) {
        &print_header($form{mypage});
        &print_message($resource{cantchange});
        &print_footer($form{mypage});
        return;
    }
	if (&frozen_reject()) {
		return;
	}

    if ($form{mypart} =~ /^\d+$/ and $form{mypart}) {
        $form{mymsg} =~ s/\x0D\x0A|\x0D|\x0A/\n/g;
        $form{mymsg} =~ s/\n*$/\n\n/ if ($form{mymsg});
        my @parts = &read_by_part($form{mypage});
        $parts[$form{mypart} - 1] = $form{mymsg};
        $form{mymsg} = join('', @parts);
    }
	if (not &is_editable($form{mypage})) {
		&print_header($form{mypage});
		&print_message($resource{cantchange});
		&print_footer($form{mypage});
		return;
	}

	# Walrus add [part edit] start
	if ($form{mypart} =~ /^\d+$/ and $form{mypart}) {
		$form{mymsg} =~ s/\x0D\x0A|\x0D|\x0A/\n/g;
		$form{mymsg} =~ s/\n*$/\n\n/ if ($form{mymsg});
		my @parts = &read_by_part($form{mypage});
		$parts[$form{mypart} - 1] = $form{mymsg};
		$form{mymsg} = join('', @parts);
	}
	# Walrus add [part edit] end

# 自動リンク処理
    foreach my $pagename (sort { length($b) <=> length($a) or $b <=> $a } keys %database) {
        if (length($pagename) < 1) { next; }
        next if $pagename =~ /^$form{mypage}$/;
	&open_autolink_index;
	for (my $i=0; $i < @autolink_index; $i++){
		my $pagename = $autolink_index[$i];
		chomp $pagename;
		next if $pagename =~ /^\Q$form{mypage}\E$/o;
		$form{mymsg} =~ s|(?<![\[\[])(\Q$pagename\E)(?![\]\]])|[[$1]]|g;
	}
	&close_autolink_index;

        $form{mymsg} =~ s|(?<![\[\[])(\Q$pagename\E)(?![\]\]])|[[$1]]|g;
#        $form{mymsg} =~ s|(?<![\[\[.+?])(\Q$pagename\E)(?![.+?\]\]])|[[$1]]|g;
#        $form{mymsg} =~ s|(?<![\[\[.*])(\Q$pagename\E)(?![.*\]\]])|[[$1]]|g;
	# ネストしている[[WikiName]]対策
	while($form{mymsg} =~ s|\[\[([^\]]*)\[\[([^\]]*)\]\]([^\[]*)\]\]|\[\[$1$2$3\]\]|go){}

        # プラグイン用[[ ]]消し込み
        # &amazon(title, ISBN, size)
        $form{mymsg} =~ s/\&(.*)\((.*)\[\[\Q$pagename\E\]\](.*),(.*),(.*)\)/\&$1\($2$pagename$3,$4,$5\)/g;
        # &color(yellow,Pagename)
        $form{mymsg} =~ s/\&(.*)\((.*),(.*)\[\[\Q$pagename\E\]\](.*)\)/\&$1\($2,$3$pagename$4\)/g;
        # &link(pagename,url)
        $form{mymsg} =~ s/\&(.*)\((.*)\[\[\Q$pagename\E\]\](.*),(.*)\)/\&$1\($2$pagename$3,$4\)/g;
        # &calendar
        $form{mymsg} =~ s/\&(.*)\((.*)\[\[\Q$pagename\E\]\](.*)\)/\&$1\($2$pagename$3\)/g;
	# プラグイン用[[ ]]消し込み
	while($form{mymsg} =~ s|\&([a-z]*)\[\[([a-z]*)\]\]([a-z]*)\(|\&$1$2$3\(|g){}
	while($form{mymsg} =~ s|\&([a-z]*)\(([^)^\n]*)\[\[([^)]*)\]\]([^)^\n]*)\)|\&$1\($2$3$4\)|g){}
	while($form{mymsg} =~ s|\#([a-z]*)\[\[([a-z]*)\]\]([a-z]*)\(|\#$1$2$3\(|g){}
	while($form{mymsg} =~ s|\#([a-z]*)\(([^)^\n]*)\[\[([^)]*)\]\]([^)^\n]*)\)|\#$1\($2$3$4\)|g){}

        # &amazon(title, ISBN, size)
        $form{mymsg} =~ s/\#(.*)\((.*)\[\[\Q$pagename\E\]\](.*),(.*),(.*)\)/\#$1\($2$pagename$3,$4,$5\)/g;
        # &color(yellow,Pagename)
        $form{mymsg} =~ s/\#(.*)\((.*),(.*)\[\[\Q$pagename\E\]\](.*)\)/\#$1\($2,$3$pagename$4\)/g;
        # &link(pagename,url)
        $form{mymsg} =~ s/\#(.*)\((.*)\[\[\Q$pagename\E\]\](.*),(.*)\)/\#$1\($2$pagename$3,$4\)/g;
        # &calendar
        $form{mymsg} =~ s/\#(.*)\((.*)\[\[\Q$pagename\E\]\](.*)\)/\#$1\($2$pagename$3\)/g;
	# URI用消し込み
	while($form{mymsg} =~ s/(mailto|http|https|ftp):([^\]\s]*)\[\[([^\]\s]*)\]\]([^\[\W]*)/$1:$2$3$4/g){}

        # html (mailto|http|https|ftp)
        $form{mymsg} =~ s/(mailto|http|https|ftp):(.*)\[\[$pagename\]\](.*)/$1:$2$pagename$3/g
	# 新規ページの場合は、既存ページへの自動リンク更新処理
	if(!exists $database{$form{mypage}} and &str_length($form{mypage}) >= $autolink_length){ 
		&open_search_index;
		for (my $i=0; $i < @search_index; $i++) {
			my $index_data = $search_index[$i];
			chomp $index_data;
			next if not $index_data =~ /\Q$form{mypage}\E/o;
			next if $index_data =~ /^$RecentChanges\t/o;
			next if $index_data =~ /^$RecentCreates\t/o;
			my ($pagename) = split(/\t/,$index_data);
			
			if (length($pagename) < 1) { next; }
			if($database{$pagename} =~ /\Q$form{mypage}\E/o){
				$database{$pagename} =~ s|(?<![\[\[])(\Q$form{mypage}\E)(?![\]\]])|[[$1]]|g;
				
				# ネストしている[[WikiName]]対策
				while ($database{$pagename} =~ s|\[\[([^\]]*)\[\[(\Q$form{mypage}\E)\]\]([^\[]*)\]\]|\[\[$1$2$3\]\]|go) {next;}
				
				# プラグイン用[[ ]]消し込み
				$database{$pagename} =~ s|\&([a-z]*)\[\[([a-z]*)\]\]([a-z]*)\(|\&$1$2$3\(|g;
				$database{$pagename} =~ s|\&([a-z]*)\(([^)^\n]*)\[\[([^)]*)\]\]([^)^\n]*)\)|\&$1\($2$3$4\)|g;
				$database{$pagename} =~ s|\#([a-z]*)\[\[([a-z]*)\]\]([a-z]*)\(|\#$1$2$3\(|g;
				$database{$pagename} =~ s|\#([a-z]*)\(([^)^\n]*)\[\[([^)]*)\]\]([^)^\n]*)\)|\#$1\($2$3$4\)|g;
				
				$database{$pagename} =~ s/(mailto|http|https|ftp):([^\[\S]*)\[\[\Q$form{mypage}\E\]\]([^\[\S]*)/$1:$2$form{mypage}$3/go;
			}
		}
		&close_search_index;
		
		# 自動リンク用インデックスの更新
		&open_autolink_index;
		unshift(@autolink_index,$form{mypage});
		&autolink_index_sort;
		&close_autolink_index;
	}
	
	
	if (&conflict($form{mypage}, $form{mymsg})) {
		return;
	}
	
	# Making diff
	if (1) {
		&open_diff;
		my @msg1 = split(/\r?\n/, $database{$form{mypage}});
		my @msg2 = split(/\r?\n/, $form{mymsg});
		$diffbase{$form{mypage}} = &difftext(\@msg1, \@msg2);
		&close_diff;
	}

    }
	$mtime = localtime;
	&update_search_index($form{mypage},$form{mymsg},$mtime);
	
	if ($form{mymsg}) {
		if(!exists $database{$form{mypage}}){
			&update_recent_creates;
		}

# ネストしている[[WikiName]]対策
    foreach my $pagename (sort { length($a) <=> length($b) or $a <=> $b } keys %database) {
        if (length($pagename) < 1) { next; }
        $form{mymsg} =~ s|\[\[([^\]]*)\[\[(\Q$pagename\E)\]\]([^\[]*)\]\]|\[\[$1$2$3\]\]|g;
    }
		$database{$form{mypage}} = $form{mymsg};
		&send_mail_to_admin($form{mypage}, "Modify");
		&set_info($form{mypage}, $info_ConflictChecker, '' . $mtime);
		if ($form{mytouch}) {
			&set_info($form{mypage}, $info_LastModified, '' . $mtime);
			&update_recent_changes;
		}
		&set_info($form{mypage}, $info_IsFrozen, 0 + $form{myfrozen});
		&print_header($CompletedSuccessfully);
		&print_message($resource{saved});
		&print_content("$resource{continuereading} @{[&armor_name($form{mypage})]}");
		&print_footer($CompletedSuccessfully);

# 新規ページの場合は、既存ページへの自動リンク更新処理
        if(!exists $database{$form{mypage}}){ 
            while ( my $pagename = each(%database) ){
                next if $pagename =~ /^$[[RecentChanges]]$/;
                next if $pagename =~ /^$[[RecentCreates]]$/;
                if (length($pagename) < 1) { next; }
                if($database{$pagename} =~ /\Q$form{mypage}\E/){
                    $database{$pagename} =~ s|(?<![\[\[])(\Q$form{mypage}\E)(?![\]\]])|[[$1]]|g;

                    # ネストしている[[WikiName]]対策
                    while ($database{$pagename} =~ s|\[\[(.*)\[\[(\Q$form{mypage}\E)\]\](.*)\]\]|\[\[$1$2$3\]\]|g) {next;}

                    # プラグイン用[[ ]]消し込み
                    $database{$pagename} =~ s/\&(.*)\((.*)\[\[$form{mypage}\]\](.*),(.*),(.*)\)/\&$1\($2$form{mypage}$3,$4,$5\)/g;
                    $database{$pagename} =~ s/\&(.*)\((.*),(.*)\[\[$form{mypage}\]\](.*)\)/\&$1\($2,$3$form{mypage}$4\)/g;
                    $database{$pagename} =~ s/\&(.*)\((.*)\[\[$form{mypage}\]\](.*),(.*)\)/\&$1\($2$form{mypage}$3,$4\)/g;
                    $database{$pagename} =~ s/\&(.*)\((.*)\[\[$form{mypage}\]\](.*)\)/\&$1\($2$form{mypage}$3\)/g;

                    $database{$pagename} =~ s/\#(.*)\((.*)\[\[$form{mypage}\]\](.*),(.*),(.*)\)/\#$1\($2$form{mypage}$3,$4,$5\)/g;
                    $database{$pagename} =~ s/\#(.*)\((.*),(.*)\[\[$form{mypage}\]\](.*)\)/\#$1\($2,$3$form{mypage}$4\)/g;
                    $database{$pagename} =~ s/\#(.*)\((.*)\[\[$form{mypage}\]\](.*),(.*)\)/\#$1\($2$form{mypage}$3,$4\)/g;
                    $database{$pagename} =~ s/\#(.*)\((.*)\[\[$form{mypage}\]\](.*)\)/\#$1\($2$form{mypage}$3\)/g;

                    $database{$pagename} =~ s/(mailto|http|https|ftp):(.*)\[\[$form{mypage}\]\](.*)/$1:$2$form{mypage}$3/g
                }
            }
        }


    if (&conflict($form{mypage}, $form{mymsg})) {
        return;
    }

    # Making diff
    if (1) {
        &open_diff;
        my @msg1 = split(/\r?\n/, $database{$form{mypage}});
        my @msg2 = split(/\r?\n/, $form{mymsg});
        $diffbase{$form{mypage}} = &difftext(\@msg1, \@msg2);
        &close_diff;
    }

    if ($form{mymsg}) {
        if(!exists $database{$form{mypage}}){
            &update_recent_creates;
        }

        $database{$form{mypage}} = $form{mymsg};
        &send_mail_to_admin($form{mypage}, "Modify");
        &set_info($form{mypage}, $info_ConflictChecker, '' . localtime);
        if ($form{mytouch}) {
            &set_info($form{mypage}, $info_LastModified, '' . localtime);
            &update_recent_changes;
        }
        &set_info($form{mypage}, $info_IsFrozen, 0 + $form{myfrozen});
        &print_header($CompletedSuccessfully);
        &print_message($resource{saved});
        &print_content("$resource{continuereading} @{[&armor_name($form{mypage})]}");
        &print_footer($CompletedSuccessfully);
    } else {
        &send_mail_to_admin($form{mypage}, "Delete");

        &update_recent_creates;
        delete $database{$form{mypage}};
        delete $infobase{$form{mypage}};
        &update_recent_changes;

        while ( my $pagename = each(%database) ){
            if (length($pagename) < 1) { next; }
            $database{$pagename} =~ s|\[\[(\Q$form{mypage}\E)\]\]|$1|g;
        }

        &print_header($form{mypage});
        &print_message($resource{deleted});
        &print_footer($form{mypage});
    }
	} else {
		&send_mail_to_admin($form{mypage}, "Delete");
		
		&update_recent_creates;
		delete $database{$form{mypage}};
		delete $infobase{$form{mypage}};
		&update_recent_changes;
		
		while ( my $pagename = each(%database) ){
			if (length($pagename) < 1) { next; }
			$database{$pagename} =~ s|\[\[(\Q$form{mypage}\E)\]\]|$1|g;
		}
		
		# 自動リンク用インデックスの更新
		&open_autolink_index;
		my @tmp = sort @autolink_index;
		my $index_point = &bsearch($form{mypage},\@tmp);
		$autolink_index[$index_point] = undef;
		@autolink_index = (@tmp);
		&autolink_index_sort;
		&close_autolink_index;
		
		&print_header($form{mypage});
		&print_message($resource{deleted});
		&print_footer($form{mypage});
	}
}
---)

- close_diff関数
- conflict関数
- frozen_reject関数
- is_editable関数
- open_diff関数
- [[print_header関数]]
- [[print_message関数]]
- [[print_content関数]]
- [[print_footer関数]]
- read_by_part関数
- send_mail_to_admin関数
- set_info関数
- [[update_recent_creates関数]]
- [[update_recent_changes関数]]

----
[[#trackback]]

先頭へ