// 2012-04-18 Checked/modified for compatibility with new data model
class CCoursePackage
{
var $ID;
var $charset;
var $LAST_ERROR = "";
var $arCourse = Array();
var $arSite = Array();
var $arItems = Array();
var $arResources = Array();
var $RefID = 1;
var $strItems = "";
var $strResourses = "";
var $arDraftFields = Array("detail_text", "preview_text", "description");
var $arPicture = Array("detail_picture", "preview_picture", "file_id");
var $arDate = Array("active_from", "active_to", "timestamp_x", "date_create");
private $replacingResId;
// 2012-04-18 Checked/modified for compatibility with new data model
public function __construct($COURSE_ID)
{
global $DB;
$this->ID = intval($COURSE_ID);
//Course exists?
$res = CCourse::GetByID($this->ID);
if (!$this->arCourse = $res->Fetch())
{
$this->LAST_ERROR = GetMessage("LEARNING_BAD_COURSE_ID_EX");
return false;
}
$res = CCourse::GetSite($this->ID);
if ($arSite = $res->GetNext())
{
$charset = $arSite["CHARSET"];
}
else
{
$this->LAST_ERROR = GetMessage("LEARNING_BAD_SITE_ID_EX");
return false;
}
//Define charset
if ($charset == '')
{
if (defined("SITE_CHARSET") && SITE_CHARSET <> '')
$charset = SITE_CHARSET;
else
$charset = "windows-1251";
}
$this->charset = $charset;
//Get chapters, lessons, questions
$this->_GetCourseContent($this->arCourse['LESSON_ID']);
//Get tests
$strSql =
"SELECT T.*, ".
$DB->DateToCharFunction("T.TIMESTAMP_X")." as TIMESTAMP_X ".
"FROM b_learn_test T ".
"WHERE T.COURSE_ID = ".intval($this->ID)." ".
"ORDER BY SORT ASC ";
$res = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__);
while ($arRes= $res->Fetch())
{
$r = ++$this->RefID;
$this->arItems[$r] = $this->_CreateContent("TES", $arRes, $r);
$this->strItems .= '- '.htmlspecialcharsbx($arRes["NAME"]).'';
$marksRes = $DB->Query(
"SELECT * FROM b_learn_test_mark WHERE TEST_ID = '" . (string) ((int) $arRes['ID']) . "'",
false, "File: ".__FILE__."
Line: ".__LINE__
);
while ($arMarksRes= $marksRes->Fetch())
{
$r = ++$this->RefID;
$this->arItems[$r] = $this->CreateTMK($arMarksRes, $r);
$this->strItems .= '- '
. '' . htmlspecialcharsbx($arMarksRes['MARK'] . ' (' . $arMarksRes['DESCRIPTION'] . ')') . ''
. '
';
}
$this->strItems .= ' ';
$this->strResourses .= ''.$this->_GetResourceFiles($r).'';
}
}
// 2012-04-18 Checked/modified for compatibility with new data model
function CreatePackage($PACKAGE_DIR)
{
if ($this->LAST_ERROR <> '')
return false;
//Add last slash
if (mb_substr($PACKAGE_DIR, -1, 1) != "/")
$PACKAGE_DIR .= "/";
$path = $_SERVER["DOCUMENT_ROOT"].$PACKAGE_DIR;
CheckDirPath($path);
if (!is_dir($path) || !is_writable($path))
{
$this->LAST_ERROR = GetMessage("LEARNING_BAD_PACKAGE");
return false;
}
RewriteFile($path."/res1.xml", $this->_CreateCourseToc());
RewriteFile($path."/imsmanifest.xml", $this->CreateManifest());
//XML Resource Data
foreach ($this->arItems as $res_id => $content)
{
RewriteFile($path."/res".$res_id.".xml", $content);
}
//Resource
$dbres_path = $path."/dbresources/";
CheckDirPath($dbres_path);
foreach ($this->arResources as $res_id => $arFiles)
{
$res_path = $path."/resources/res".$res_id."/";
CheckDirPath($res_path);
foreach ($arFiles as $arFile)
{
if (array_key_exists("DB", $arFile))
{
$arTempFile = CFile::MakeFileArray($arFile["DB"]);
if($arTempFile && isset($arTempFile["tmp_name"]))
@copy($arTempFile["tmp_name"], $dbres_path.$arFile["ID"]);
}
else
{
@copy($_SERVER["DOCUMENT_ROOT"].$arFile["SRC"], $res_path.$arFile["ID"]);
}
}
}
return true;
}
// 2012-04-18 Checked/modified for compatibility with new data model
function CreateManifest()
{
global $DB;
if ($this->LAST_ERROR <> '')
return false;
$this->createQuestionItems($this->arCourse["LESSON_ID"]);
$strManifest = "<"."?xml version=\"1.0\" encoding=\"".$this->charset."\"?".">\n";
$strManifest .= '';
//
$strManifest .= '';
$strManifest .= '- '.htmlspecialcharsbx($this->arCourse["NAME"]).'';
$strManifest .= $this->strItems;
$strManifest .= '
';
$strManifest .= '';
//
$strManifest .= ''.$this->_GetResourceFiles(1).'';
$strManifest .= $this->strResourses;
$strManifest .= '';
$strManifest .= '';
return $strManifest;
}
// 2012-04-18 Checked/modified for compatibility with new data model
function _GetCourseContent($parentLessonId, $DEPTH_LEVEL = 1)
{
global $DB;
$res = CLearnLesson::GetListOfImmediateChilds (
$parentLessonId,
array( // order
'EDGE_SORT' => 'asc'
)
);
while ($arRes= $res->Fetch())
{
$arRes['ID'] = $arRes['LESSON_ID']; // for compatibility
if ($arRes['IS_CHILDS'] == '1')
$itemType = 'CHA';
else
$itemType = 'LES';
if (CLearnLesson::IsPublishProhibited($arRes['LESSON_ID'], $parentLessonId))
$arRes['META_PUBLISH_PROHIBITED'] = 'Y';
else
$arRes['META_PUBLISH_PROHIBITED'] = 'N';
$r = ++$this->RefID;
$this->arItems[$r] = $this->_CreateContent($itemType, $arRes, $r);
$this->strItems .= '- '.htmlspecialcharsbx($arRes["NAME"]).'';
$this->strResourses .= ''.$this->_GetResourceFiles($r).'';
$this->createQuestionItems($arRes["ID"]);
// Load content recursively for chapters
if ($arRes['IS_CHILDS'] == '1')
$this->_GetCourseContent($arRes["ID"], $DEPTH_LEVEL+1);
$this->strItems .= "
";
}
}
// 2012-04-18 Checked/modified for compatibility with new data model
function _CreateCourseToc()
{
$str = "<"."?xml version=\"1.0\" encoding=\"".$this->charset."\"?".">\n";
$str .= "";
foreach ($this->arCourse as $key => $val)
{
$strDelayed = '';
$key = mb_strtolower($key);
if ($key === 'site_id')
continue;
$str .= "<".$key.">";
if (in_array($key, $this->arDraftFields) && $val <> '')
{
$str .= "_ReplaceImages($val, 1)."]]>";
}
elseif (in_array($key, $this->arDate) && $val <> '')
{
$str .= MakeTimeStamp($val);
}
elseif (in_array($key, $this->arPicture) && $val <> '')
{
$src = CFile::GetPath($val);
$ext = GetFileExtension($src);
$this->arResources[1][] = Array("DB" => $val, "SRC"=>$src, "ID"=>$val.".".$ext);
$str .= $val.".".$ext;
$rs = CFile::GetByID($val);
if ($arFileData = $rs->Fetch())
{
$strDelayed = '<' . $key . '_description' . '>'
. htmlspecialcharsbx($arFileData['DESCRIPTION'])
. '' . $key . '_description' . '>';
}
}
else
{
$str .= htmlspecialcharsbx($val);
}
$str .= "".$key.">\n";
$str .= $strDelayed;
}
$str .= "";
return $str;
}
// 2012-04-18 Checked/modified for compatibility with new data model
function _GetResourceFiles($res_id)
{
$str = "";
if (is_set($this->arResources,$res_id))
foreach ($this->arResources[$res_id] as $arFile)
if (is_set($arFile,"DB"))
$str .= '';
else
$str .= '';
return $str;
}
// 2012-04-18 Checked/modified for compatibility with new data model
function _CreateContent($TYPE, $arParams, $res_id)
{
$str = "<"."?xml version=\"1.0\" encoding=\"".$this->charset."\"?".">\n";
$str .= '';
foreach ($arParams as $key => $val)
{
$strDelayed = '';
$key = mb_strtolower($key);
if ($key === 'site_id')
continue;
$str .= "<".$key.">";
if (in_array($key, $this->arDraftFields) && $val <> '')
{
$str .= "_ReplaceImages($val, $res_id)."]]>";
}
elseif (in_array($key, $this->arPicture) && $val <> '')
{
$src = CFile::GetPath($val);
$ext = GetFileExtension($src);
$this->arResources[$res_id][] = Array("DB" => $val, "SRC"=>$src, "ID"=>$val.".".$ext);
$str .= $val.".".$ext;
$rs = CFile::GetByID($val);
if ($arFileData = $rs->Fetch())
{
$strDelayed = '<' . $key . '_description' . '>'
. htmlspecialcharsbx($arFileData['DESCRIPTION'])
. '' . $key . '_description' . '>';
}
}
elseif (in_array($key, $this->arDate) && $val <> '')
{
$str .= MakeTimeStamp($val);
}
else
{
$str .= htmlspecialcharsbx($val);
}
$str .= "".$key.">\n";
$str .= $strDelayed;
}
$str .= "";
return $str;
}
// 2012-04-18 Checked/modified for compatibility with new data model
function _replace_img($matches)
{
$src = $matches[3];
if($src <> "" && is_file($_SERVER["DOCUMENT_ROOT"].$src))
{
$dest = basename($src);
$uid = RandString(5);
$res_id = 1;
$this->arResources[$this->replacingResId][] = array("SRC"=>$src, "ID"=> $uid.".".$dest);
return stripslashes($matches[1].$matches[2]."cid:resources/res".$this->replacingResId."/".$uid.".".$dest.$matches[4].$matches[5]);
}
return stripslashes($matches[0]);
}
// 2012-04-18 Checked/modified for compatibility with new data model
function _ReplaceImages($text, $res_id)
{
$this->replacingResId = $res_id;
return preg_replace_callback("/(<.+?src\\s*=\\s*)([\"']?)(.*?)(\\2)(.*?>)/is", array($this, "_replace_img"), $text);
}
private function createQuestionItems($lessonId)
{
global $DB;
$strSql = "SELECT * FROM b_learn_question WHERE LESSON_ID=".$lessonId." ORDER BY SORT ASC ";
$q = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__);
while ($arQRes = $q->Fetch())
{
$r = ++$this->RefID;
$this->arItems[$r] = $this->CreateQTI($arQRes, $r);
$this->strItems .= '- '.htmlspecialcharsbx($arQRes["NAME"]).'
';
$this->strResourses .= ''.$this->_GetResourceFiles($r).'';
}
}
// 2012-04-18 Checked/modified for compatibility with new data model
function CreateQTI($arParams, $res_id = 1)
{
global $DB;
if ($this->LAST_ERROR <> '')
return false;
$str = "<"."?xml version=\"1.0\" encoding=\"".$this->charset."\"?".">\n";
$str .= "";
$str .= '- ';
$str .= ''.htmlspecialcharsbx($arParams["NAME"]).'';
if (intval($arParams["FILE_ID"]) > 0)
{
$arFile = CFile::GetFileArray($arParams["FILE_ID"]);
if ($arFile)
{
$name = $arFile["ID"].'.'.GetFileExtension($arFile["FILE_NAME"]);
$this->arResources[$res_id][] = Array("DB" => $arFile["ID"], "SRC"=>$arFile["SRC"], "ID"=>$name);
$str .= '';
$str .= '' . htmlspecialcharsbx($arFile['DESCRIPTION']) . '';
}
}
$str .= "";
switch ($arParams["QUESTION_TYPE"])
{
case "M":
$qType = 'Multiple';
break;
case "T":
$qType = 'Text';
break;
case "R":
$qType = 'Sort';
break;
default:
$qType = 'Single';
break;
}
$str .= '';
$strSql =
"SELECT * FROM b_learn_answer WHERE QUESTION_ID = '".intval($arParams["ID"])."' ORDER BY SORT ASC ";
$res = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__);
$cond = "";
while ($arAnwer = $res->Fetch())
{
if ($arAnwer["CORRECT"] == "Y")
$cond .= 'ANS'.$arAnwer["ID"].'';
$str .= ''.htmlspecialcharsbx($arAnwer["ANSWER"]).'';
}
$str .= "";
$str .= "";
$str .= "".$cond."".$arParams["POINT"]."";
$str .= "";
$str .= "";
$str .= "";
if ($arParams["DESCRIPTION"] <> '')
{
$str .= "_ReplaceImages($arParams["DESCRIPTION"], $res_id)."]]>";
}
$str .= "";
$str .= "".$arParams["DESCRIPTION_TYPE"]."";
$str .= "" . htmlspecialcharsbx($arParams["INCORRECT_MESSAGE"]) . "";
$str .= "".$arParams["SELF"]."";
$str .= "".$arParams["SORT"]."";
$str .= "".$arParams["ACTIVE"]."";
$str .= "";
$str .= " ";
return $str;
}
function CreateTMK($arParams, $res_id = 1)
{
$str = "<"."?xml version=\"1.0\" encoding=\"".$this->charset."\"?".">\n"
. ''
. '' . (int) $arParams['SCORE'] . ''
. '' . htmlspecialcharsbx($arParams['MARK']) . ''
. '' . htmlspecialcharsbx($arParams['DESCRIPTION']) . ''
. '';
return $str;
}
}