Trackerプラグインでページに隙間があるとそこを利用してしまう

  • ページ: BugTrack
  • 投稿者: kak?
  • 優先順位: 低
  • 状態: 完了
  • カテゴリー: プラグイン
  • 投稿日: 2005-01-18 (火) 20:48:33
  • バージョン:
  • リリース予定バージョン: 1.5.2

メッセージ

(official:続・質問箱/539)(official:続・質問箱/522)

現在の tracker プラグインでは番号1のページから最後のページまでをトレースしていき、隙間があるとそのページを利用するアルゴリズムになっています。

この辺には好き嫌いがあるのかもしれませんが、単純に一番最後の次のページを作成する方が計算量的にも早いし、上の質問箱のようなこともおこらないかと思います。隙間を再利用すると関係のないバックアップも残ってしまっていますし。


  • 動作は追っていないのですが。バックアップファイルを改変してしまうのはあんまり好ましくないですね。毎回ユニークなIDを発行してくれないというのも厳密な番号管理上問題になりそうです。改造はできそうですか? -- henoheno 2005-01-18 (火) 22:39:42
  • 2つ方法があると思いますが、どちらにすべきでしょうか?
    1. get_existpages() ですべてのページを取得し、たとえば「質問箱」という文字列を含むページのみをとりだし、ソートし、最後のページを見つけ、番号をとりだす。
    2. どこかに最後の番号をキャッシュしておき、それを取り出す。
    1. はお分かりの通り遅そうです。ページが増えるにつれてさらに遅くなります。が、ページを作るとき1度だけだと考えれば別にいいのかもしれない。2. の cache でいいですよね? -- kak? 2005-01-19 (水) 01:10:17
  • ちなみに問題箇所は 110 行からの
    	// ページ名を決定
    	$base = $post['_base'];
    	$num = 0;
    	$name = (array_key_exists('_name',$post)) ? $post['_name'] : '';
    	if (array_key_exists('_page',$post))
    	{
    		$page = $real = $post['_page'];
    	}
    	else
    	{
    		$real = is_pagename($name) ? $name : ++$num;
    		$page = get_fullname('./'.$real,$base);
    	}
    	if (!is_pagename($page))
    	{
    		$page = $base;
    	}
    
    	while (is_page($page))
    	{
    		$real = ++$num;
    		$page = "$base/$real";
    	}
    のところです。$real = is_pagename($name) ? $name : ++$num; あたりで何を意図しているのかよくわかりません。-- kak? 2005-01-19 (水) 01:10:17
  • ページ名は明示的にフォームから[_name]で指定することもできますよね。明示的に指定されていれば、その値をページ名として利用し、指定がされなければ、連番を使うといった仕様だったと思います。しろくろのへや:tracker.inc.phpの予約項目をご覧ください。( is_pagename()や is_page()は lib/func.phpで定義されてますね ) -- jjyun? 2005-01-19 (水) 02:31:03
    • $real = is_pagename($name) ? $name : ++$num; は [_name] フォームで指定して名前がページ名として使用できない場合(変な記号が入っているとか)、++$num の値を利用しているわけですが、なぜ ++$num なのだろう。となぜ1なのだろうと思ったわけです。結果、あえて $base/1 のようなページ名を作らせて、連番ループに入らせているみたいですね。ちなみに [_page] と [_name] のフォームを両方作っていると、たとえば [_page] フォームで何も指定していないとしても、if (array_key_exists('_page',$post)) にヒットして、[_name] 用の処理が行われないという不具合があるようです。ちなみに [_name] は $base/$name のような相対指定、[_page] は $page そのものが使われる絶対ページ指定のようです。しろくろさんのページには form に対しての [_page] はかかれていません。 -- kak? 2005-01-19 (水) 03:00:52
  • 単純にバックアップがあるかどうかを確認して重複チェックするとか。 -- teanan 2005-01-19 (水) 02:48:51
    - 	while (is_page($page))
    +	while (is_page($page) || backup_file_exists($page))
    	{
    		$real = ++$num;
    		$page = "$base/$real";
    	}
    • こんな感じで。試してみたところは大丈夫そうです。 -- teanan 2005-01-19 (水) 02:57:33
    • それがよさそうですね。キャッシュを作ったとしてもその中身をいじられると結局同じですから。でも、バックアップファイルなどもきれいさっぱり消されている場合は、隙間のページを利用するわけで、先の質問箱のようにユーザーが不思議に思う状況がでてこないとも限らないですよね。-- kak? 2005-01-19 (水) 03:05:41
    • でもまぁめんどくさいし、バックアップが壊されなければいいということで、こんなかんじで
      	$base = $post['_base'];
      	$name = (array_key_exists('_name',$post)) ? $post['_name'] : '';
      	$_page = (array_key_exists('_page',$post)) ? $post['_page'] : '';
      	if ( is_pagename( $_page ) )
      	{
      		$page = $real = $_page;
      	}
      	else if ( is_pagename( $name ) )
      	{
      		$real = $name;
      		$page = get_fullname('./'.$real,$base);
      	}
      	else
      	{
      		$page = $base; // is_page($page) にヒットさせ連番ループに入らせる
      	}
      	while (is_page($page) || _backup_file_exists($page) )
      	{
      		$real = ++$num;
      		$page = "$base/$real";
      	}
      上の [_page] があるときは [_name] が働かない。の不具合も修正しています。自分の環境(1.4.4)では_backup_file_exists($page) のように _ が先頭についていたのですが。-- kak? 2005-01-19 (水) 03:16:55
  • ところで、[_name] [_page] で指定したページ名がすでに存在していた場合、うむをいわさず連番ページを作成しているようなのですが、いいのですかね?まぁいいか。 -- kak? 2005-01-19 (水) 03:20:36
  • 対応しました。バックアップは考慮せず、既存の最も大きい番号+1を新しい番号とします。(bugtrackプラグインと同じ) commit:32c7cdee02 -- umorigu 2017-06-13 (火) 03:43:56

bugtrack プラグインのページチェックロジックを、tracker プラグインに取り入れてほしい

投稿日: 2007-11-07 (水) 23:05:33

上の話題とは少し違う方法なのですが、bugtrack プラグインがページを作る時には、まず50ごとにチェックしてそれから・・・、という処理をしています。

1から順番に数えていく今のロジックだと、100を超える数を数えるのにはそれなりに時間がかかるので、できればtracker にこの処理を取り入れてもらえないでしょうか。

cvs:plugin/tracker.inc.php (1.22)

 	$name = isset($post['_name']) ? $post['_name'] : '';
-	if (isset($post['_page'])) {
+	if (isset($post['_page']) && $post['_page'] != '') {
 		$real = $page = $post['_page'];
 	} else {
 		$real = is_pagename($name) ? $name : ++$num;
 		$page = get_fullname('./' . $real, $base);
 	}
 	if (! is_pagename($page)) $page = $base;
-	while (is_page($page)) {
-		$real = ++$num;
-		$page = $base . '/' . $real;
-	}
+	if (is_page($page)) {
+		$jump = 0;
+		do {
+			$num   = $jump;
+			$jump += 50;
+			$page = $base . '/' . $jump;
+		} while (is_page($page));
+		do {
+			$real = ++$num;
+			$page = $base . '/' . $real;
+		} while (is_page($page));
+	}
 
 	$config = isset($post['_config']) ? $post['_config'] : '';

最初にif (is_page($page)) で括ることで、[_page] や[_name] で指定した場合に、途中で連番になってしまわないようにしています(if (! is_pagename($page)) に引っ掛かった場合を除く)。

if (is_page($page)) で括っているので、その中はwhile ループではなく、do-while ループにしています。連続で同じチェックしても意味無いですし。


  • $post['_page'] が空文字のとき対策を追加 -- 2007-11-10 (土) 16:29:16

ベースページが未作成の時、特定の条件でベースページに投稿できる

投稿日: 2007-11-07 (水) 23:05:33

tracker にはベースページを作らなくても、パラメータとしてベースページを指定することで、他のページからも投稿できる機能があります。

しかし、次の部分の中で不正なページ名だった場合$page = $base としているので、ベースページが未作成だった場合、連番付きページではなくペースページに投稿してしまうと思います。

	$base  = isset($post['_base'])  ? $post['_base']  : '';
	$refer = isset($post['_refer']) ? $post['_refer'] : '';

	// $page name to add will be decided here
	$num  = 0;
	$name = isset($post['_name']) ? $post['_name'] : '';
	if (isset($post['_page'])) {
		$real = $page = $post['_page'];
	} else {
		$real = is_pagename($name) ? $name : ++$num;
		$page = get_fullname('./' . $real, $base);
	}
	if (! is_pagename($page)) $page = $base;

この部分で不正なページと判断されるのは$post['_page'] に不正な文字が含まれている場合か、$base に不正な文字が含まれているか、$base が空文字の時*1です。

ふと思ったんですけど、$base が空文字の時だと$page も空文字になって'.txt' てファイル作ったりしませんよね?

改修案の素案
cvs:plugin/tracker.inc.php (1.22)

	$num  = 0;
 	$name = isset($post['_name']) ? $post['_name'] : '';
 	if (isset($post['_page'])) {
 		$real = $page = $post['_page'];
 	} else {
		$real = is_pagename($name) ? $name : ++$num;
 		$page = get_fullname('./' . $real, $base);
 	}
-	if (! is_pagename($page)) $page = $base;
+	if (! is_pagename($page)) {
+		if (! is_pagename($base)) {
+			return array(
+				'msg'  => 'エラーメッセージ',
+				'body' => 'エラーメッセージ'
+			);
+		}
+		$page = $base . '/' . ++$num;
+	}
 	while (is_page($page)) {

素案なんで、エラーメッセージの部分がいいかげんなのは勘弁してください。



*1 $page = '/' . $real となるから

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-06-13 (火) 03:43:56
Site admin: PukiWiki Development Team

PukiWiki 1.5.1+ © 2001-2016 PukiWiki Development Team. Powered by PHP 5.6.30-0+deb8u1. HTML convert time: 0.740 sec.

OSDN