Приложения Приложение 1. public static function Upload($dir, $local = 0, $from_temp = 1) { global $root; if ($from_temp) $dir = $root."temp/".$dir; else $dir = $root.$dir; $manifest = new DOMDocument("1.0","utf-8"); if (@$manifest->load($dir."/META-INF/manifest.xml")) { $xpath = new DOMXPath($manifest); $xpath->registerNamespace("lom","http://ltsc.ieee.org/xsd/LOM"); //guid $guid = ""; $list = $xpath->query("//lom:lom/lom:general/lom:identifier[lom:catalog=\"X-RUS-FCIOR\"]/lom:entry"); $node = $list->item(0); if ($node != null) $guid = iconv('UTF-8','CP1251',$node->nodeValue); $sql = "SELECT id, folder, published, version FROM tbmodule WHERE guid = '%s'"; try { $db = new DataBase(); $rec = $db->query($sql, array($guid)); if ($rec->num_rows() == 1) { if (self::Validate($dir)) { $id = $rec->record['id']; $folder = $root."db/".$rec->record['folder']; $isstd = self::isStdFolder($dir); $catopenid = self::$dfv['catopenid']; $levelid = self::$dfv['interactlevelid']; if ($isstd) { #@_DelDir($folder."/MODELERS"); @_DelDir($folder."/DATA/scene"); @_DelDir($folder."/DATA/components"); @_CopyDir($dir."/DATA/scene", $folder."/DATA/scene"); @_CopyDir($dir."/DATA/components", $folder."/DATA/components"); #@_CopyDir($dir."/MODELERS", $folder."/MODELERS"); //??!!! //@copy($dir."/DATA/skin/textStylesDef.xml", $folder."/DATA/skin/textStylesDef.xml"); $levelid = self::calcInterLevel($folder, $catopenid); } else { @_DelDir($folder); @_CopyDir($dir, $folder); } $datatypes = self::skanDataTypes($folder); $version = ""; if ($rec->record['published']) { $v_arr = explode(".",$rec->record['version']); $v_arr[count($v_arr)-1] = (int)$v_arr[count($v_arr)-1] + 1; $version = ", version = '".implode(".",$v_arr)."'"; } if ($isstd) { $db->exec_query("UPDATE tbmodule SET isstd = '1', datatypes = '{$datatypes}', interactlevelid='{$levelid}', catopenid='{$catopenid}' {$version} WHERE id = '{$id}'"); } else { $db->exec_query("UPDATE tbmodule SET isstd = '0', datatypes = '{$datatypes}' {$version} WHERE id = '{$id}'"); } if ($local != 1) _SetMessage("Модуль успешно загружен", 'message'); CLLog::log('module upload OK: '.$id); return $id; } else { if ($local != 1) _SetMessage("Ошибка! Модуль не прошёл верификацию"); return false; } } else { //module not registered what's next? CLLog::log('module upload not registered: '.$dir); if ($local != 1) _SetMessage("Ошибка! Модуль не зарегистрирован в системе"); return false; } } catch (Exception $e) { CLLog::error('module upload db error: '.$e->getMessage()); if ($local != 1) _SetMessage("Ошибка доступа к БД"); return false; } } else { CLLog::error('module upload manifest load failed: '.$dir); if ($local != 1) _SetMessage("Ошибка! Не найден файл с метаданными"); return false; } } private function metaGenerate($root, $tmpl, $dst) { /* $guid $fname $name $description $keywords_str $version $date $authors_str $metalastupdate $datatypes_str $size $cat_open $type $interact_level $com_edu_level $contact_time $edu_level_id $edu_level $class $discipline_str $edu_purpose_str $lcharacter*/ $manifest = new DOMDocument("1.0","utf-8"); if (@$manifest->load($root.$tmpl)) { $xpath = new DOMXPath($manifest); $xpath->registerNamespace("lom","http://ltsc.ieee.org/xsd/LOM"); //guid $temp = $this->fields['guid']->getValue(); $value = iconv('CP1251','UTF-8',$temp); $list = $xpath->query("//lom:lom/lom:general/lom:identifier[lom:catalog=\"X-RUS-FCIOR\"]/lom:entry"); $node = $list->item(0); if ($node != null) $node->nodeValue = $value; //catalogid $this->mfolder = $this->makeFolderName(); $list = $xpath->query("//lom:lom/lom:general/lom:identifier[lom:catalog=\"x-oms-module\"]/lom:entry"); $node = $list->item(0); if ($node != null) $node->nodeValue = $this->mfolder; //title $list = $xpath->query("//lom:lom/lom:general/lom:title/lom:string[@language=\"ru\"]"); $node = $list->item(0); if ($node != null) { $node->nodeValue = iconv('CP1251','UTF-8',$this->makeTitle()); } //description $description = $this->fields['description']->getValue(); if (!$this->fields['description']->isFP()) { $title = $this->fields['name']->getValue(); $s = str_replace("\$title","{$title}",$description); $description = $s; } $list = $xpath->query("//lom:lom/lom:general/lom:description/lom:string[@language=\"ru\"]"); $node = $list->item(0); if ($node != null) $node->nodeValue = iconv('CP1251','UTF-8',$description); //keywords $list = $xpath->query("//lom:lom/lom:general"); $node = $list->item(0); if ($node != null) { $keywords = explode("\r\n",$this->fields['keywords']->getValue()); foreach ($keywords as $keyword) { $key = $manifest->createElement("keyword"); $tmp = $manifest->createElement("string"); $tmp->nodeValue = iconv('CP1251','UTF-8',$keyword); $atr = $manifest->createAttribute("language"); $atr->nodeValue = "ru"; $tmp->appendChild($atr); $key->appendChild($tmp); $node->appendChild($key); } } //version $list = $xpath->query("//lom:lom/lom:lifeCycle/lom:version/lom:string[@language=\"none\"]"); $node = $list->item(0); if ($node != null) $node->nodeValue = $this->fields['version']->getValue(); //pubdate $date = $this->fields['pubdate']->getValue(); $list = $xpath->query("//lom:lom/lom:lifeCycle/lom:contribute[lom:role[lom:value=\"publisher\"]]/lom:date/lom:dateTime"); $node = $list->item(0); if ($node != null) $node->nodeValue = $date; //author $list = $xpath->query("//lom:lom/lom:lifeCycle/rl:lastUpdating"); $node = $list->item(0); if ($node != null) { $authors = $this->fields['author']->getValue(); foreach ($authors as $author) { #$sql = "select vCard from tbauthors where id = ".$author; $sql = "select vCard from tboandp where id = ".$author; $rec = $this->db->query($sql); if ($rec->num_rows()==1) { $xml = "LOMv1.0 author "; $xml .= iconv('CP1251','UTF-8',$rec->record[0]); $xml .= " "; $tmp = $manifest->createDocumentFragment(); $tmp->appendXML($xml); $node->parentNode->insertBefore($tmp,$node); } } $roles = $this->fields['roles']->getValue(); foreach ($roles as $r_id => $v_arr) { foreach ($v_arr as $v_id) { $sql = "select v.vCard, r.name, r.source from tboandp v, tblomroles r where v.id = '".$v_id."' AND r.id = '".$r_id."'"; $rec = $this->db->query($sql); if ($rec->num_rows()==1) { $xml = "".$rec->record[2]." ".$rec->record[1]." "; $xml .= iconv('CP1251','UTF-8',$rec->record[0]); $xml .= " "; $tmp = $manifest->createDocumentFragment(); $tmp->appendXML($xml); $node->parentNode->insertBefore($tmp,$node); } } } } //update $date = $this->fields['update']->getValue(); $list = $xpath->query("//lom:lom/lom:lifeCycle/rl:lastUpdating/lom:dateTime"); $node = $list->item(0); if ($node != null) $node->nodeValue = $date; //metaupdate $date = date('Y-m-d'); $list = $xpath->query("//lom:lom/lom:metaMetadata/lom:contribute[lom:role[lom:value=\"creator\"]]/lom:date/lom:dateTime"); $node = $list->item(0); if ($node != null) $node->nodeValue = $date; //format $list = $xpath->query("//lom:lom/lom:technical"); $pnode = $list->item(0); $list = $xpath->query("//lom:lom/lom:technical/lom:size"); $node = $list->item(0); if ($node != null) { $formats = $this->fields['datatypes']->getValue(); $sql = "select id, mime from tbdatatypes"; try { $rec = $this->db->query($sql); } catch (Exception $e) { } $n = $rec->num_rows(); for ($i=0; $i < $n; $i++) { if (array_search($rec->record['id'],$formats) !== false) { $tmp = $manifest->createElement("format"); $tmp->nodeValue = $rec->record['mime']; $pnode->insertBefore($tmp,$node); } $rec->next_record(); } } //fcior:opennesCategory $list = $xpath->query("//lom:lom/lom:technical/fcior:opennesCategory/lom:value"); $node = $list->item(0); if ($node != null) { $sql = "select category from tbcatopen where id = ".$this->fields['catopenid']->getValue(); $rec = $this->db->query($sql); $node->nodeValue = $rec->record[0]; } //type $list = $xpath->query("//lom:lom/lom:educational/lom:learningResourceType/lom:value"); $node = $list->item(0); if ($node != null) { $sql = "select ltype from tbtypes where id = ".$this->fields['typeid']->getValue(); $rec = $this->db->query($sql); $node->nodeValue = $rec->record[0]; } //interactivitylevel $list = $xpath->query("//lom:lom/lom:educational/lom:interactivityLevel/lom:value"); $node = $list->item(0); if ($node != null) { $sql = "select level from tbilevels where id = ".$this->fields['interactlevelid']->getValue(); $rec = $this->db->query($sql); $node->nodeValue = $rec->record[0]; } //education level $list = $xpath->query("//lom:lom/lom:educational/lom:context/lom:value"); $node = $list->item(0); $lid = 0; $level = ""; $clevel = ""; if ($node != null) { $sql = "select lid,level,clevel from tbedulevels where id = ".$this->fields['edulevelid']->getValue(); try { $rec = $this->db->query($sql); $clevel = $rec->record[2]; $lid = $rec->record[0]; $level = $rec->record[1]; } catch (Exception $e) { } $node->nodeValue = $clevel; } //contact_time $list = $xpath->query("//lom:lom/lom:educational/lom:typicalLearningTime/lom:duration"); $node = $list->item(0); if ($node != null) { $node->nodeValue = "PT".$this->fields['contacttime']->getValue()."M"; } //edu_level_id $list = $xpath->query("//lom:lom/lom:classification[lom:purpose[lom:value=\"educational level\"]]/lom:taxonPath/lom:taxon/lom:id"); $node = $list->item(0); if ($node != null) $node->nodeValue = $lid; //edu_level $list = $xpath->query("//lom:lom/lom:classification[lom:purpose[lom:value=\"educational level\"]]/lom:taxonPath/lom:taxon/lom:entry/lom:string[@language=\"ru\"]"); $node = $list->item(0); if ($node != null) $node->nodeValue = iconv('CP1251','UTF-8',$level); //discipline $discipline =iconv('CP1251','UTF-8',$this->parent_rub->getDiscipline(true)); $fragment = $manifest->createDocumentFragment(); $fragment->appendXML($discipline); $list = $xpath->query("//lom:lom/lom:classification[lom:purpose[lom:value=\"discipline\"]]/lom:taxonPath"); $node = $list->item(0); if ($node != null) $node->appendChild($fragment); //class if ($clevel == 'school') { $list = $xpath->query("//lom:lom/lom:classification[lom:purpose[lom:value=\"class\"]]/lom:taxonPath/lom:taxon/lom:entry/lom:string[@language=\"ru\"]"); $node = $list->item(0); if ($node != null) $node->nodeValue = $this->fields['class']->getValue(); $list = $xpath->query("//lom:lom/lom:classification[lom:purpose[lom:value=\"class\"]]/lom:taxonPath/lom:taxon/lom:id"); $node = $list->item(0); if ($node != null) $node->nodeValue = $this->fields['class']->getValue(); } else { $list = $xpath->query("//lom:lom/lom:classification[lom:purpose[lom:value=\"class\"]]"); $node = $list->item(0); if ($node != null) $node->parentNode->removeChild($node); } //edu_purpose_str $list = $xpath->query("//lom:lom/lom:classification[lom:purpose[lom:value=\"educational purpose\"]]/lom:taxonPath/lom:taxon/lom:entry/lom:string[@language=\"ru\"]"); $node = $list->item(0); $eid = ""; if ($node != null) { try { $sql = "select purpose,code from tbedupurpose where id = ".$this->fields['edupurposeid']->getValue(); $rec = $this->db->query($sql); $node->nodeValue = iconv('CP1251','UTF-8',$rec->record[0]); $eid = $rec->record[1]; } catch (Exception $e) { } } $list = $xpath->query("//lom:lom/lom:classification[lom:purpose[lom:value=\"educational purpose\"]]/lom:taxonPath/lom:taxon/lom:id"); $node = $list->item(0); if ($node != null) $node->nodeValue = $eid; //lcharacter if (($this->fields['edulevelid']->getValue() >= 2) && ($this->fields['edulevelid']->getValue() <= 5)) { $list = $xpath->query("//lom:lom/lom:classification[lom:purpose[lom:value=\"learning character\"]]/lom:taxonPath/lom:taxon/lom:entry/lom:string[@language=\"ru\"]"); $node = $list->item(0); if ($node != null) { try { $sql = "select lcharacter from tblcharacter where id = ".$this->fields['learningcharid']->getValue(); $rec = $this->db->query($sql); $node->nodeValue = iconv('CP1251','UTF-8',$rec->record[0]); } catch (Exception $e) { } } $list = $xpath->query("//lom:lom/lom:classification[lom:purpose[lom:value=\"learning character\"]]/lom:taxonPath/lom:taxon/lom:id"); $node = $list->item(0); if ($node != null) $node->nodeValue = $this->fields['learningcharid']->getValue(); } else { $list = $xpath->query("//lom:lom/lom:classification[lom:purpose[lom:value=\"learning character\"]]"); $node = $list->item(0); if ($node != null) $node->parentNode->removeChild($node); } //restrictions $ograns = $this->fields['ogranid']->getValue(); if ($ograns !== '0') { $list = $xpath->query("//lom:lom/lom:classification[lom:purpose[lom:value=\"accessibility restrictions\"]]/lom:taxonPath"); $node = $list->item(0); if ($node != null) { try { foreach ($ograns as $ogran) { $sql = "select name from tbogran where id = ".$ogran; $rec = $this->db->query($sql); if ($rec->num_rows()==1) { $xml = "".$ogran." "; $xml .= iconv('CP1251','UTF-8',$rec->record[0]); $xml .= " "; $tmp = $manifest->createDocumentFragment(); $tmp->appendXML($xml); $node->appendChild($tmp); } } } catch (Exception $e) { } } } else { $list = $xpath->query("//lom:lom/lom:classification[lom:purpose[lom:value=\"accessibility restrictions\"]]"); $node = $list->item(0); if ($node != null) $node->parentNode->removeChild($node); } $folder = $dst; $mname = $folder."/META-INF/manifest.xml"; $manifest->save($mname); //size $size = _ScanDir($folder,'size'); $slen = strlen($size); $nsize = $size + $slen; $nslen = strlen($nsize); $size = $nsize + ($nslen - $slen) + 6; $list = $xpath->query("//lom:lom/lom:technical/lom:size"); $node = $list->item(0); if ($node != null) $node->nodeValue = $size; $manifest->save($mname); } else { CLLog::error('module manifest file load error' + $this->fields['id']->getValue()); } } private static function skanDataTypes($folder) { $def_mime = array("application/xml","image/jpeg","image/png","text/xml","text/javascript"); $types = array(); $allowed_ext = array(); try { $db = new DataBase(); $rec = $db->query("SELECT extension, mime, id FROM tbdatatypes"); for ($i = 0; $i<$rec->num_rows(); $i++) { $types[$rec->record[2]] = array(); $types[$rec->record[2]][0]=$rec->record[0]; $types[$rec->record[2]][1]=$rec->record[1]; $allowed_ext[] = $rec->record[0]; $rec->next_record(); } } catch (Exception $e) { return null; } $ret = @_ScanDir($folder,'mime',$allowed_ext); foreach ($ret as $value) { foreach ($types as $mime) { if ($mime[0] == $value) { array_push($def_mime,$mime[1]); break; } } } $def_mime = array_unique($def_mime); $s = ""; foreach ($def_mime as $value) { foreach ($types as $_id => $mime) { if ($mime[1] == $value) { if ($s != "") $s .= ";".$_id; else $s = $_id; break; } } } return $s; } private static function checkFileName(&$node, $fld) { $src = iconv('UTF-8','CP1251',$node->nodeValue); #src в формате \DATA\... $src = str_replace("\\","/",$src); $path_info = pathinfo($src); $old_name = $fld.$src; if (_Translit($path_info['basename'],$fname)) { $new_name_to_xml = $path_info['dirname']."/".$fname; $new_name_to_xml = str_replace("/","\\",$new_name_to_xml); $new_name = $fld.$path_info['dirname']."/".$fname; if (@rename($old_name,$new_name)) { $node->nodeValue = $new_name_to_xml; return true; } } return false; } private static function stepsAnylyze($m_folder, $step_list) { $ret = array(1,1); //0 - interactlevel, 1 - catopenid $db = new DataBase(); $db->exec_query("SET NAMES 'UTF8'"); try { $level_rec = $db->query("SELECT xpath, value FROM tbxpath WHERE type = '1'"); $copen_rec = $db->query("SELECT xpath, value FROM tbxpath WHERE type = '2'"); $src_rec = $db->query("SELECT xpath FROM tbxpath WHERE type = '3'"); } catch (Exception $e) { return $ret; } $scene_folder = $m_folder."/DATA/scene/"; $comp_folder = $m_folder."/DATA/components/pict/"; $levels = array("II.1"); $catopenid = 1; $files = array(); for ($i = 0; $i < $step_list->length; $i++) { $src = $step_list->item($i)->attributes->getNamedItem("src")->value; $src = $scene_folder.$src; if (($src != $scene_folder) && (file_exists($src))) { $need_save = false; $step = @DOMDocument::load($src); if ($step !== false) { $sxpath = new DOMXPath($step); //interact level $level_rec->_reset(); for ($j = 0; $j < $level_rec->num_rows(); $j++) { $list = @$sxpath->query($level_rec->record[0]); if ($list->length !== 0) { $levels[] = $level_rec->record[1]; } $level_rec->next_record(); } //list of files $src_rec->_reset(); for ($j = 0; $j < $src_rec->num_rows(); $j++) { $list = $sxpath->query($src_rec->record[0]); for ($k = 0; $k < $list->length; $k++) { if ($list->item($k)->nodeValue != "") { $need_save = $need_save | self::checkFileName($list->item($k), $m_folder); $files[] = mb_strtolower(str_replace("\\","/",$m_folder.$list->item($k)->nodeValue)); } } $src_rec->next_record(); } //catopenid if ($catopenid != 2) { $copen_rec->_reset(); for ($j = 0; $j < $copen_rec->num_rows(); $j++) { $list = @$sxpath->query($copen_rec->record[0]); if ($list->length !== 0) { $catopenid = (int)$copen_rec->record[1]; if ($catopenid == 2) break; } $copen_rec->next_record(); } } if ($need_save) { $step->save($src); } } } } //remove unhandled files $all_files = @_ScanDir($comp_folder,'files'); $files_to_delete = array_diff($all_files,$files); foreach ($files_to_delete as $file) { //TODO think about //@unlink($file); //_WriteLog("scaner: file to delete {$file}"); } //calc interactivity level $levels = array_unique($levels); $l2 = 0; $l3 = 0; foreach ($levels as $level) { if (strpos($level,"III.") !== false) $l3++; else if (strpos($level,"II.") !== false) $l2++; } if ($l3 >= 2) $ret[0] = 3; else if (($l2 >= 3) || (($l2 == 2) && ($l3 == 1))) $ret[0] = 2; else $ret[0] = 1; $ret[1] = $catopenid; return $ret; } Приложение 2.