XOOPSメモ

XOOPSに関する記録を残します。ここに記した方法を用いることによって生じる如何なる不利益について関知致しません。At your own riskでお願い致します。
なお、以下で例に用いるmyxoops.jpは架空のドメインです。

同一サーバ上にXOOPSを2つインストールする

XOOPSは、MySQLデータベースを利用します(PostgreSQLを利用するバージョンを試みているグループもいますが、piCalなど定番のモジュールがインストールできないなど、発展途上なので、MySQLとともに利用するのが無難です)。 データベース名はxoops2とするのが標準です。このデータベースの中に、XOOPSが目的ごとにテーブルを作成します。例えばユーザに関する情報はテーブル'user'に記録されますが、実際にMySQLにアクセスする際のテーブル名は、 XOOPSインストールの際に設定したテーブル接頭語(prefix)と'_'を前に繋いだものになります。 prefixがデフォルト値のxoops2の場合、ユーザに関する情報はテーブル'xoops2_user'となります。(mysqlコマンドを使ってデータベースxoops2のテーブルを一覧してみると確認できます。)
prefixを違ったものにしてXOOPSをインストールすれば、各XOOPSがそれぞれ固有のテーブルを利用することになり、同じサーバ上に複数個のXOOPSサイトを構築することが可能になっています。
データベース名を変えてしまうことも可能です。しかし、以下に示すような複数XOOPS間の情報共有はデータベース名が異っていると困難なので、データベース名はxoops2で共通とし、prefixのみを変えるようにします。

MySQLについて

mysqlコマンドの防忘録
データベース一覧
# mysql -u xoops
mysql> show databases;
mysql> quit
データベースxoops2のテーブル一覧
# mysql -u xoops
mysql> show tables from xoops2;
mysql> quit

2つのXOOPSサイトでユーザ情報等を共有する

この情報は、ここから得ました。
ユーザ情報は、MySQLデータベースのテーブル'users', 'groups', 'groups_users_link' に記録されます。ただし、実際のMySQLにアクセスする際のテーブル名は、 XOOPSインストールの際に設定したテーブル接頭語(prefix)と'_'を前に繋いだものになります。 通常は、2つのXOOPSサイトではprefixを異なったものにするので、XOOPSサイトごとにユーザ情報のテーブルは個別であり、結果としてユーザ情報はXOOPSサイトごとに固有のものになります。
ユーザ情報を共通にするには、参照するテーブルを共通にすればよいことが分かります。
母体側XOOPSのprefixを'xoops2'とする場合、参照側XOOPSの /class/database/database.phpの一部を以下のように書き換えます。 すなわち、ユーザ情報に関するテーブル参照の際に、テーブル名の前に加えられる prefixを参照側のものではなく、母体側のprefixに強制的に変更します。
function prefix($tablename='')
{
	$mother_tables = array( 'users', 'groups', 'groups_users_link' );
	if ( in_array( $tablename, $mother_tables) ) {
		return 'xoops2_'. $tablename;
	} elseif ( $tablename != '' ) {
		return $this->prefix .'_'. $tablename;
	} else {
		return $this->prefix;
	}
}

2つのXOOPSサイトでpiCalのデータベースを共有する

XOOPSが参照するMySQLデータベースのテーブル名を両方のXOOPSサイトで 同じにすることでデータを共通化することができます。 母体側XOOPSのprefixを'xoops2'とする場合、参照側XOOPSの /class/database/database.phpの一部を以下のように書き換えます。 詳細は、上の「2つのXOOPSサイトでユーザ情報等を共有する」を参照してください。
なお、piCalはユーザ、グループを識別します。だからこそ、登録データについて ユーザ単位やグループ単位で閲覧制限をかけることができるのですが、 単にpiCalのデータのみを共有しただけでは、 一方のサイトであるユーザが登録したpiCalデータを、 他方のサイトで同じユーザID(XOOPS内部の管理上のID)が割り当てられた 別のユーザが閲覧・編集できてしまう問題が起こります。 そのため、実際には2つのサイトでユーザ、グループも共有した状態で使用する必要があります。
以下の書き換え例でも、ユーザ情報を共有するようになっています。
function prefix($tablename='')
{
	$mother_tables = array( 'users', 'groups', 'groups_users_link', 'pical_event', 'pical_cat', 'pical_plugins' );
	if ( in_array( $tablename, $mother_tables) ) {
		return 'xoops2_'. $tablename;
	} elseif ( $tablename != '' ) {
		return $this->prefix .'_'. $tablename;
	} else {
		return $this->prefix;
	}
}

2つのXOOPSサイトでニュースを共有する

上に述べた方法を参考に、ニュースモジュールが使用するテーブル'topics'と'stories'を 共有します。

tinyDモジュールでindex.php?id=xxというリンクだけでなくindex.php?name=xxx.htmlというリンクを利用する

この情報は、ここ(XOOPS/tinyD/サブメニューをファイル名にする)から得ました。
例えばtiny0でWRAP3でラップしたファイルがxxx.htmlの場合、URLが
http://myxoops.jp/modules/tiny0/index.php?id=3    や
http://myxoops.jp/modules/tiny0/rewrite/tc_3.html
のようになり、見栄えがいまいちです。 見栄えに目をつむったとしても、 そもそも、ラップしたファイルのidが何番でアクセスされるのか対応を調べないとページ間でリンクが記述出来ず、また、ラップを変更するとidが変更されるかも知れないことを 考えると、わずらわしすぎます。
上の情報にしたがって書き換えると、ファイルxxx.htmlをラップすると
http://myxoops.jp/modules/tiny0/index.php?name=xxx.html
で参照できるようになります。
ここまでくれば、例えばtiny0のディレクトリに置いた.htaccessによってrewriteを指定し、
http://myxoops.jp/modules/tiny0/xxx.html
としてラップしたxxx.htmlを参照することが可能になります。

tinyDモジュールを利用した場合にhttp://myxoops.jp/modules/tiny0/index.php?name=top.htmlをhttp://myxoops.jp/top.htmlに見せる

http://myxoops.jp/top.html
を表示すると実際には
http://myxoops.jp/modules/tiny0/index.php?name=top.html または上のrewriteを行っていれば
http://myxoops.jp/modules/tiny0/top.html
が参照されるようにする方法です。
これは、.htaccessによってrewriteを行います。つまり、XOOPS自身の設定ではなく、あくまでもhttpdサーバ(apache)の設定です。
http://myxoops.jp/のドキュメントルートに以下の内容の.htaccessを作成します。
RewriteEngine On
RewriteRule ^(top.html)$ http://myxoops.jp/modules/tiny0/index.php?name=$1 [L]
同じようにして、より多くのRewriteRuleを追加することができます。
一つ問題があり、tinyDを複数インストールした場合(例えばtiny0とtiny1)、両方に同じ ファイル名(例えばindex.html)があるとRewriteRuleの記述が難しくなります。
最も簡単な解決策は、参照するファイル名を変えることです。例えばindex0.htmlとindex1.html のように参照します。
RewriteEngine On
RewriteRule ^index0.html$ http://myxoops.jp/modules/tiny0/index.php?name=index.html [L]
RewriteRule ^index1.html$ http://myxoops.jp/modules/tiny1/index.php?name=index.html [L]
フォルダを変えて例えばindex.htmlとsub/index.htmlや、sub0/index.htmlとsub1/index.htmlのように参照したいといった場合もRewriteRuleを適切に記述すれば可能と思いますが、試していません。

tinyDとmultiMenuを併用した場合にmultiMenu上のリンクをhttp://myxoops.jp/modules/tiny0/index.php?name=top.htmlではなくhttp://myxoops.jp/top.htmlに見せる

multiMenuモジュールでは、リンクとして"&['モジュール名']"と書くと、そのモジュールを参照するサブメニュー("-['モジュール名']..."形式のリンク)を表示している間はサブメニューを展開したままとする、という機能があります。
これは非常に便利で見た目もよいのですが、参照・表示されるURLが例えば「http://myxoops/modules/tiny0/top.html」のようにモジュール名を含んだものになってしまいます。 上の「tinyDモジュールを利用した場合にhttp://myxoops.jp/modules/tiny0/index.php?name=top.htmlをhttp://myxoops.jp/top.htmlに見せる」によって「http://myxoops.jp/top.html」でアクセスできるようにしたのに、multiMenuの部分には"modules/モジュール名"が残ってしまい、あまりかっこよくありません。 閲覧者に無用にサイトの内部構成を見せてしまうことにもなります。
そこで、modules/multiMenu/blocks/multimenu.phpを書き換え、multiMenuモジュールが生成するURLから'modules/モジュール名/'の部分を削ってしまうことにします。
例えばtinyDモジュールを"tiny0", "tiny1"のように"tiny"+数字としてインストールしたとします。 このとき、例えば
	$imenu['link'] = XOOPS_URL."/modules/".$moduledir[1]."/".$moduledir[2];
のようになっている部分を以下のように書き換えます。
//	$imenu['link'] = XOOPS_URL."/modules/".$moduledir[1]."/".$moduledir[2];
	if( strncmp($moduledir[1], "tiny", 4) == 0 ){
		$imenu['link'] = XOOPS_URL."/".$moduledir[2];
	}else{
		$imenu['link'] = XOOPS_URL."/modules/".$moduledir[1]."/".$moduledir[2];
	}
書き換えるべき場所は何箇所かあります。
モジュール名が"tiny"+数字以外の場合やtinyD以外のモジュールを使用している場合にも、 if文の条件を適切に設定すれば対応できると思います。
なお、これが正しく機能するためには、上に説明した 「tinyDモジュールを利用した場合にhttp://myxoops.jp/modules/tiny0/index.php?name=top.htmlをhttp://myxoops.jp/top.htmlに見せる」を設定しておく必要があります。
また、複数のtinyDモジュールで同じファイル名のラップを使用している場合にもややこしいことになるので注意が必要です。




以下、テンプレート等の直接書き換えは批判的意見もありますが、どのファイルをどのように書き換えるかの記録として。

ゲストに見せる登録ユーザ情報を削る

http://myxoops.jp/userinfo.php?id=xxxをアクセスすると登録ユーザに関する情報が表示されます。サイトの運用形態によっては、ゲストに見せる必要があるのか?と思うものもあります。そこで、ユーザ情報を登録ユーザにのみ見せ、ゲストには見せないように します。
modules/system/templates/system_userinfo.htmlを編集します。 ログインユーザにのみ見せたい部分を
<{if $xoops_isuser==true}>
<{/if}>
で囲います。
編集後は、モジュール管理でシステム管理モジュールをアップデートします。
なお、以下の「ゲストによる登録ユーザ情報閲覧を禁止する」の方が良いかも知れません。

ゲストによる登録ユーザ情報閲覧を禁止する

この情報は、ここから得ました。
ゲストがuserinfo.phpをアクセスしたとき、index.phpにリダイレクトするようにします。
userinfo.phpの中で最初にある
if (is_object($xoopsUser)) {
	...
}else{
	...
}
の部分で、else節がゲストの場合に実行されます。 else節の中をすべてコメントアウトし、以下の1行をelse節に加えます。
redirect_header("index.php",3,_NOPERM);

登録ユーザ情報で「xxxさんの基本情報」で"xxx"がユーザ名になっているのを本名を表示するようにする

userinfo.phpの中で
$xoopsTpl->assign('lang_allaboutuser', sprintf(_US_ALLABOUT,$thisUser->getVar('uname')));
を以下のように編集します。
if( $thisUser->getVar('name') != "" ){
	$xoopsTpl->assign('lang_allaboutuser', sprintf(_US_ALLABOUT,$thisUser->getVar('name')));
}else{
	$xoopsTpl->assign('lang_allaboutuser', sprintf(_US_ALLABOUT,$thisUser->getVar('uname')));
}

ニュース記事で投稿者名に付けられているユーザ情報へのリンクをゲスト向けには外す

ニュース記事で、投稿者名の部分にはユーザ情報表示ページへのリンクが 貼られています。ユーザIDが見えるため少し気分が悪いので、ゲスト権限で閲覧する場合にはリンクを貼らないようにします。
ニュースモジュールのindex.phpとarticle.phpの中で以下の部分
$story['poster'] = "<a href='".XOOPS_URL."/userinfo.php?uid=".$sarray[$i]->uid()."'>".$story['poster']."</a>";
を以下のように書き換えます。
if( $xoopsUser ){
	$story['poster'] = "<a href='".XOOPS_URL."/userinfo.php?uid=".$sarray[$i]->uid()."'>".$story['poster']."</a>";
}else{
	$story['poster'] = $story['poster'];
}
なお、以下の「ニュース記事でゲスト向けには投稿者名を削る」の方が良いかも知れません。

ニュース記事でゲスト向けには投稿者名を削る

デフォルトではニュースの各記事には投稿者名が表示されます。 ここを本名で表示する方法が分かりません。このままでは、投稿者のログインユーザ名がばればれなので、ゲストの場合は投稿者名の表示をしないようにします。
modules/news/templates/news_item.htmlを編集します。 この中で、'<{$lang_postedby}> <{$story.poster}>'の部分が 投稿者を表示する部分なので、<span> ... </span>を考慮して前後を
<{if $xoops_isuser==true}>
<{/if}>
で囲います。
編集後は、モジュール管理でニュースモジュールをアップデートします。
なおこの変更を施した場合、上の「ニュース記事で投稿者名に付けられているユーザ情報へのリンクをゲスト向けには外す」はあまり意味がなくなります。
あなたは人目のお客様です。 (平成18年8月9日から)