内輪の話です。SCORMコンテンツの仕様を、ときどき変更する必要が生じます。そこで、古いコンテンツを読み込んで新しいものに書き換えるphpスクリプトを書きました。ubuntu上で、zipがインストールされて入れば動くと思います。まずkanaikeにあるファイル(例えばこれ)をダウンロードして、解凍すると、transというフォルダーが作られます。その中身は下記。
- trans.php
- readme.txt
- simple_question
- source
- temporary
- zip
メインとなるスクリプトはtrans.php です。simple_question, source, temporary, zip は作業用のフォルダーで、それぞれ下記のような役割です。
- simple_question : 新しいSCORMの雛形ファイルがあるフォルダー
- source : 古い仕様のSCORMファイル(zipファイル)を置くフォルダー。
- temporary : 作業用の一時ファイルが書き込まれるフォルダー
- zip : 修正されたzipファイルが書き込まれるフォルダー
使用方法は、まず sourceフォルダーに古いSCORMファイルをコピーします(複数可)。後は、端末でtransフォルダーに移動して、下記のコマンドを打つだけです。
-
php trans.php
修正されたSCORMコンテンツが,zipフォルダーに出来上がります。
スクリプトの動作は、最初に古いSCORMファイルが解凍されて、temporaryフォルダーにコピーされます。次に、simple_questionフォルダーにある新しい雛形ファイルを解凍したファイルに上書きします。その後,新しい問題の形式にあわせてコンフィグレーション用のファイル(config.xml)を修正します。このためのコードが長々とあって,最後は、それを圧縮してzipフォルダーにコピーして終了です。
trans.phpのコードです。
<?php
// 書き込む設定
// 現在、採点サーバーは変更しない。それゆえ下記の値は利用していない。
$servername = "kanaike.susi.oita-u.ac.jp";
$cgi_url = "/php_simple_question_recursion/answertest_for_stack3_ver2.php";
$tex_url = "/php_simple_question_recursion/fortex_xml_dimension.php";
$folder = "./source/";
$xmlText = <<< end_of_quote
<?xml version="1.0" encoding="utf-8"?>
<root>\n
<folder>$folder</folder>\n
end_of_quote;
if ($handle = opendir($folder)) {
// echo "Directory handle: $handle\n";
// echo "Entries:\n";
/* ディレクトリをループする際の正しい方法です */
while (false !== ($entry = readdir($handle))) {
if (eregi('zip',$entry) ) {
// echo "$entry\n";
$xmlText = $xmlText.'<filename>'.$entry."</filename>\n";
}
}
closedir($handle);
}
$xmlText = $xmlText."</root>\n";
echo $xmlText;
$xml = simplexml_load_string($xmlText);
// 以前のファイルを消す
exec("rm -rf ./temporary/*");
exec("rm -rf ./zip/*");
foreach ($xml->filename as $filename) {
// ファイル毎に時間をかえないとね
$stamp = microtime();
list($msec, $sec) = explode(" ", $stamp);
$mustamp = $stamp*1000000;
$timestamp = $sec.$mustamp;
$zip_file = './source/' . $filename;
$foldername = mb_eregi_replace('\.zip','',$filename);
exec("mkdir ./temporary/$foldername");
exec("cd ./temporary/$foldername/ ; unzip ../../$zip_file");
// 新しいファイルで上書き
exec("cp -f -r ./simple_question/glossary ./temporary/$foldername/");
exec("cp -f -r ./simple_question/history ./temporary/$foldername/");
exec("cp -f -r ./simple_question/jquery ./temporary/$foldername/");
exec("cp -f -r ./simple_question/jquery.treeview ./temporary/$foldername/");
exec("cp -f ./simple_question/AC_OETags.js ./temporary/$foldername/");
exec("cp -f ./simple_question/batu.gif ./temporary/$foldername/");
exec("cp -f ./simple_question/imsmanifest.xml ./temporary/$foldername/");
exec("cp -f ./simple_question/index.html ./temporary/$foldername/");
exec("cp -f ./simple_question/index_sentence.html ./temporary/$foldername/");
exec("cp -f ./simple_question/insert_panel.txt ./temporary/$foldername/");
exec("cp -f ./simple_question/maru.gif ./temporary/$foldername/");
exec("cp -f ./simple_question/message.jpg ./temporary/$foldername/");
exec("cp -f ./simple_question/playerProductInstall.swf ./temporary/$foldername/");
exec("cp -f ./simple_question/poweredbyflash.swf ./temporary/$foldername/");
exec("cp -f ./simple_question/q_style.css ./temporary/$foldername/");
exec("cp -f ./simple_question/scorm_functions_test.js ./temporary/$foldername/");
// config の処理
$config_text = file_get_contents("./temporary/$foldername/".'configfile.xml');
$config_xml = simplexml_load_string($config_text);
// 古いinfoへの対応
if (!($config_xml->info->where)) {
$config_xml->info->where = "kanaike.susi.oita-u.ac.jp";
$config_xml->info->when = "100";
}
// editがあってもなくても
$config_xml->edit->where = $servername;
$config_xml->edit->when = $timestamp;
$xml_server_url = $config_xml->server->url;
$xml_cgi_url = $cgi_url;
$xml_tex_url = $tex_url;
$xml_title = $config_xml->title;
$xml_info_where = $config_xml->info->where;
$xml_info_when = $config_xml->info->when;
$xml_edit_where = $config_xml->edit->where;
$xml_edit_when = $config_xml->edit->when;
$xml_passmark = $config_xml->passmark;
$xml_TextHeight = $config_xml->TextHeight;
// key がない場合もある
if ($config_xml->key) {
$public_key = (string) $config_xml->key;
} else {
$public_key = 'YTozOntpOjA7czoxMjg6Ilf2eJ3ruWeu53QPEdsmUy+aXVek/gRRr52Cs7cETrJSapu/zIo6pb6CkTxnC/StbXdCha5hqFzhEsPmVaMDm6J/46N4LRnGJ0Ioz/4JB5HOZ4qToQTYCIM08bzHa0wh+23bYc8eMwbI1n74n2oosutTLfqP+GceE0EJ6wC6WtyJIjtpOjE7czo2NDoiZaQiod9dnBpZ11XUUpEPjsxKyQeGBIPBf748uzl49nSzMbDubOspqCZl42GgHp3bWdgWldNR0A6Ny0mIBv/7ciI7aToyO3M6NjoicHVibGljIjt9';
}
$xmlstr = <<< end_of_quote
<?xml version="1.0" encoding="utf-8"?>
<root>
<server>
<url>$xml_server_url</url>
</server>
<cgi>
<url>$xml_cgi_url</url>
</cgi>
<tex>
<url>$xml_tex_url</url>
</tex>
<title>$xml_title</title>
<info>
<where>$xml_info_where</where>
<when>$xml_info_when</when>
</info>
<edit>
<where>$xml_edit_where</where>
<when>$xml_edit_when</when>
</edit>
<key>$public_key</key>
<passmark>$xml_passmark</passmark>
<textHeight>$xml_TextHeight</textHeight>
end_of_quote;
// 入れ子のquestionに対応
$i = 0;
$str = '';
foreach ($config_xml->question as $q) {
$i = $i + 1;
$someobj = new make_xml();
$str = $str.$someobj->action($q,$i);
}
$xmlstr = $xmlstr.$str;
$xmlstr = $xmlstr."</root>";
//echo $xmlstr."\n";
$configfile = fopen("./temporary/$foldername/configfile.xml","w");
fputs($configfile,$xmlstr);
fclose($configfile);
// zip を作る
passthru("cd ./temporary/$foldername ; zip -r -q ../../zip/$foldername.zip .");
} // each filename
// 入れ子のXMLを作成
class make_xml {
function __constructor() {
}
public function action($q,$i) {
$str = '';
$str = $str."<question>\n\n<num>".$i."</num>\n";
$str = $str."<answerTest>".$q->AnswerTest."</answerTest>\n";
if ($q->size) {
$str = $str.'<size>'.$q->size."</size>\n";
}
if ($q->x) {
$str = $str.'<x>'.$q->x."</x>\n";
}
if ($q->y) {
$str = $str.'<y>'.$q->y."</y>\n";
}
// 最初のquestionにのみSAnsを付ける
if ($q->size) {
$str = $str."<sans></sans>\n";
}
$str = $str.'<tans>'.$q->TAns."</tans>\n";
$str = $str.'<ansTestOpt>'.$q->AnsTestOpt."</ansTestOpt>\n";
if ($q->operation->text) {
$str = $str."<operation><text><![CDATA[".$q->operation->text."]]></text></operation>\n";
}
if ($q->true) {
$str = $str."<true>\n<message>".$q->true->message."</message>\n</true>\n";
}
if ($q->false) {
$str = $str."<false>\n<message>".$q->false->message."</message>\n</false>\n\n";
}
if ($q->question) {
$newq = $q->question;
$someobj = new make_xml();
$str = $str.$someobj->action($newq,$i);
}
$str = $str."</question>\n\n";
return $str;
}
} // end of class
?>