SCORMコンテンツの修正phpスクリプト

8 5月

内輪の話です。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

?>