dokeos-metadata
[ class tree: dokeos-metadata ] [ index: dokeos-metadata ] [ all elements ]

Source for file md_funcs.php

Documentation is available at md_funcs.php

  1. <?php /*                                   <!-- Dokeos metadata/md_funcs.php -->
  2.                                                              <!-- 2006/12/15 -->
  3.  
  4. <!-- Copyright (C) 2006 rene.haentjens@UGent.be - see note at end of text    -->
  5.  
  6. */
  7.  
  8. /**
  9. ============================================================================== 
  10. *   Dokeos Metadata: common functions and mdstore class
  11. *
  12. *   This script requires xmd.lib.php and xht.lib.php (Dokeos inc/lib).
  13. *
  14. *   Note on the funny characters used in mds_update_xml_and_mdt:
  15. *
  16. *   ! and ~ and ,   are handled by xmd_update, see xmd.lib.php
  17. *   ~~ !! ; and =   are handled here; note that = excludes newlines in value
  18. *
  19. *   path!elem       create new element (not for attributes!)
  20. *   path=value      assign new value to existing element or value to attribute
  21. *   path~           delete element (you cannot delete an attribute)
  22. *   ~~              delete the whole xmldoc and the DB entry
  23. *   !!              this (xml) document contains the course keywords
  24. *
  25. *   path1,path2,...;subpath=value   for all elements in path1, path2, ...
  26. *                   assign value to subpath (see also xmd_update_many)
  27. *
  28. *   @package dokeos.metadata
  29. ============================================================================== 
  30. */
  31.  
  32.  
  33. // FETCH GET/POST-DATA; GENERAL FUNCTIONS ------------------------------------->
  34.  
  35. if (isset($getpostvars&& is_array($getpostvars))
  36.   foreach ($getpostvars as $gpvar)
  37.     if (is_string($gpvar&& (isset($_POST[$gpvar]|| isset($_GET[$gpvar])))
  38.     {
  39.         $val = isset($_POST[$gpvar]$_POST[$gpvar$_GET[$gpvar];
  40.         $GLOBALS[$gpvarget_magic_quotes_gpc(stripslashes($val$val;
  41.     }
  42.     
  43. function fgc($filename)
  44. {
  45.     $fp fopen($filename'rb')$buffer fread($fpfilesize($filename));
  46.     fclose($fp)return $buffer// file_get_contents: PHP >= 4.3.0
  47. }
  48.  
  49.  
  50. function give_up($msg)
  51. {
  52.     echo '<p align="center">MetaData:<br><b>? '
  53.         htmlspecialchars($msg)'</b></p>'exit;
  54.  
  55.  
  56. function getpar($name$description$default '')
  57. {
  58.     $value = isset($_GET[$value strtolower($name)]$_GET[$value'';
  59.     $value get_magic_quotes_gpc(stripslashes($value$value;
  60.     if (!$value$value $default;
  61.     if ($value == ''give_up('URL parameter ' strtoupper($name' - ' 
  62.                 $description ' - is required');
  63.     
  64.     define(strtoupper($name)$value);
  65. }
  66.  
  67.  
  68. function get_course_path()
  69. {
  70.     return function_exists('api_get_path'// 1.6
  71.         api_get_path('SYS_COURSE_PATH'api_get_path(SYS_PATH);  // 1.5.4
  72. }
  73.  
  74. function get_course_web()
  75. {
  76.     return function_exists('api_get_path'// 1.6
  77.         api_get_path('WEB_COURSE_PATH'api_get_path(WEB_PATH);  // 1.5.4
  78. }
  79.  
  80.  
  81. function define_htt($htt_file$urlp$course_path)
  82. {
  83.     ($htt_file_contents @fgc($htt_file))
  84.         or give_up('Templates file "' $htt_file '" is missing...');
  85.     
  86.     $xhtDoc new xhtdoc($htt_file_contents);
  87.     if ($xhtDoc->htt_error
  88.         give_up('Templates file "' $htt_file '": ' $xhtDoc->htt_error);
  89.     
  90.     $xhtDoc->xht_param['self'api_get_self($urlp;
  91.     
  92.     $xhtDoc->xht_param['dateTime'date('Y-m-d');
  93.     
  94.     $ckw $course_path '/CourseKwds.js';
  95.     define('KEYWORDS_CACHE'get_course_path($ckw);
  96.     
  97.     if (file_exists(KEYWORDS_CACHE)) $kcdt 
  98.         htmlspecialchars(date('Y/m/d H:i:s'filemtime(KEYWORDS_CACHE)));
  99.     
  100.     $xhtDoc->xht_param['keywordscache'$kcdt ?
  101.         '<script type="text/javascript" src="' get_course_web($ckw '"></script>' 
  102.         '<br /><small><i>(CourseKwds cache: ' $kcdt ')</i></small>' '';
  103.     
  104.     return $xhtDoc;
  105. }
  106.  
  107.  
  108. function make_uri()
  109. {
  110.     $regs array()// for use with ereg()
  111.     
  112.     $uri strtr(ereg_replace(
  113.         "[^0-9A-Za-z\xC0-\xD6\xD8-\xF6\xF8-\xFF\*\(\('!_.-]""_"
  114.         api_get_setting('siteName'))"\\""_");  // allow letdigs, and _-.()'!*
  115.     
  116.     if (($p strpos($uri'.')) !== FALSE
  117.         $uri substr($uri0$p);
  118.     if (ereg('^([^/]+//)?([^/\?]+)[/\?]',api_get_path(WEB_PATH).'/',$regs))
  119.         if (ereg('([^\.]+)(\.ca)?(\.[^\.]+)?'strrev($regs[2])$regs))
  120.             $uri str_replace('.''-'
  121.                 strrev($regs[1].$regs[2].$regs[3])) ':' $uri;
  122.     $uri 'urn:' strtolower($uri);
  123.     while (substr($uri-1)=='.'$uri substr($uri,0,-1);
  124.     
  125.     return $uri;
  126. }
  127.  
  128.  
  129. // IEEE LOM: DEFAULT XML AND DUBLIN CORE MAPPING ------------------------------>
  130.  
  131. $ieee_xml = <<<EOD
  132.  
  133. <!-- {-XML-} -->
  134.  
  135. <item>
  136.   <metadata>
  137.     <lom xmlns="http://ltsc.ieee.org/xsd/LOM">
  138.       <general>
  139.         <identifier><catalog>{-H {-P siteUri-}-}.</catalog><entry>{-H {-P entry-}-}</entry></identifier>
  140.         <title><string language="{-H {-P mdlang-}-}">{-H {-P title-}-}</string></title>
  141.         <language>{-H {-P lang-}-}</language>
  142.         <description><string language="{-H {-P mdlang-}-}">{-H {-P description-}-}</string></description>
  143.         <coverage><string language="{-H {-P mdlang-}-}">{-H {-P coverage-}-}</string></coverage>
  144.       </general>
  145.       <lifeCycle>
  146.         <version><string language="xx">0.5</string></version>
  147.         <status><source>LOMv1.0</source><value>draft</value></status>
  148.         <contribute>
  149.           <role><source>LOMv1.0</source><value>author</value></role>
  150.           <entity>{-H {-P author-}-}</entity>
  151.           <date><dateTime>{-H {-P dateTime-}-}</dateTime></date>
  152.         </contribute>
  153.       </lifeCycle>
  154.       <metaMetadata>
  155.         <metadataSchema>ADLv1.3</metadataSchema>
  156.       </metaMetadata>
  157.       <technical>
  158.         <format>{-H {-P format-}-}</format>
  159.         <size>{-H {-P size-}-}</size>
  160.         <location>{-H {-P location-}-}</location>
  161.       </technical>
  162.       <educational>
  163.         <learningResourceType><source>LOMv1.0</source><value>narrative text</value></learningResourceType>
  164.       </educational>
  165.       <rights>
  166.         <cost><source>LOMv1.0</source><value>yes</value></cost>
  167.         <copyrightAndOtherRestrictions><source>LOMv1.0</source><value>yes</value></copyrightAndOtherRestrictions>
  168.         <description><string language="{-H {-P mdlang-}-}">{-L MdCopyright-}</string></description>
  169.       </rights>
  170.       <classification>
  171.         <purpose><source>LOMv1.0</source><value>educational objective</value></purpose>
  172.       </classification>
  173.     </lom>
  174.   </metadata>
  175. </item>
  176. <!-- {--} -->
  177. EOD;
  178.  
  179. $ieee_dcmap_e array(
  180. 'Identifier'=>      'metadata/lom/general/identifier[1]',
  181. 'Title'=>           'metadata/lom/general/title[1]',
  182. 'Language'=>        'metadata/lom/general/language[1]',
  183. 'Description'=>     'metadata/lom/general/description[1]',
  184. 'Coverage'=>        'metadata/lom/general/coverage[1]',
  185. 'Type'=>            'metadata/lom/educational/learningResourceType[1]',
  186. 'Date'=>            'metadata/lom/lifeCycle/contribute[1]/date',
  187. 'Creator'=>         'metadata/lom/lifeCycle/contribute[1]/entity',
  188. 'Format'=>          'metadata/lom/technical/format[1]',
  189. 'Rights'=>          'metadata/lom/rights/description[1]');
  190. // maps Dublin Core elements to xmd paths for elements (not yet complete)
  191.  
  192. $ieee_dcmap_v array(
  193. 'Identifier'=>      'metadata/lom/general/identifier[1]/entry',
  194. 'Title'=>           'metadata/lom/general/title[1]/string',
  195. 'Language'=>        'metadata/lom/general/language[1]',
  196. 'Description'=>     'metadata/lom/general/description[1]/string',
  197. 'Coverage'=>        'metadata/lom/general/coverage[1]/string',
  198. 'Type'=>            'metadata/lom/educational/learningResourceType[1]/value',
  199. 'Date'=>            'metadata/lom/lifeCycle/contribute[1]/date/dateTime',
  200. 'Creator'=>         'metadata/lom/lifeCycle/contribute[1]/entity',
  201. 'Format'=>          'metadata/lom/technical/format[1]',
  202. 'Rights'=>          'metadata/lom/rights/description[1]/string');
  203. // maps Dublin Core elements to xmd paths for values (not yet complete)
  204.  
  205.  
  206. // KEYWORD TREE --------------------------------------------------------------->
  207.  
  208. function define_kwds($mdo
  209. {
  210.     if (!($newtext trim(@fgc(get_course_path($mdo->mdo_course['path'
  211.             '/document' $mdo->mdo_path ))))
  212.     {
  213.         unlink(KEYWORDS_CACHE)return;
  214.     }
  215.                                     // templates to define the tree as JScript object
  216.     $xhtDocKw new xhtdoc(<<<EOD
  217.     
  218. <!-- {-KWTREE_OBJECT-} -->
  219.  
  220. KWTREE_OBJECT = {n:"", ti:"{-X @title-}"
  221. , c:[{-R * C DOWN_THE_KWTREE-}]};
  222.  
  223. document.write(traverseKwObj(KWTREE_OBJECT, '', 0)); KWDS_ARRAY.sort();
  224.  
  225. <!-- {-DOWN_THE_KWTREE-} -->
  226. {-T number > 1 , -}{n:"{-V @.-}"{-D cm {-X @comment-}-}{-T cm != empty , cm:"{-P cm-}"-}{-D pt {-X @postit-}-}{-T pt != empty , pt:"{-P pt-}"-}{-R * P empty-}{-T number >= 1 
  227. , c:[-}{-T number >= 1 R * C DOWN_THE_KWTREE-}{-R * P empty-}{-T number >= 1 ]-}}
  228.  
  229. <!-- {--} -->
  230. EOD
  231.     );  // traverseKwObj (md_script) generates clickable tree and populates KWDS_ARRAY
  232.  
  233.     
  234.     if ($xhtDocKw->htt_error
  235.         give_up('KwdTree template (metadata/md_funcs): ' $xhtDocKw->htt_error);
  236.     
  237.     $xhtDocKw->xht_xmldoc new xmddoc(explode("\n"$newtext));
  238.     if ($xhtDocKw->xht_xmldoc->error)
  239.         give_up('CourseKwds (metadata/md_funcs): XML error: ' 
  240.         $xhtDocKw->xht_xmldoc->error);
  241.     
  242.     if (count($xhtDocKw->xht_xmldoc->children[0]2)
  243.     {
  244.         unlink(KEYWORDS_CACHE)return;
  245.     }
  246.     
  247.     $fileHandler @fopen(KEYWORDS_CACHE'w');
  248.     @fwrite($fileHandler$xhtDocKw->xht_fill_template('KWTREE_OBJECT'));
  249.     @fclose($fileHandler);
  250. }
  251.  
  252.  
  253. // METADATA STORE ------------------------------------------------------------->
  254.  
  255. class mdstore
  256. {
  257.  
  258.  
  259. function mds_get($eid$column 'mdxmltext'$must_exist '')  // none: FALSE
  260. {
  261.     if (($mdt mysql_fetch_array($this->_query("SELECT " $column 
  262.         " FROM " MDS_TABLE " WHERE "$eid)))) return $mdt[$column];
  263.     
  264.     if ($must_existgive_up($must_exist $this->_coldat('eid'$eid));
  265.     
  266.     return FALSE;
  267. }
  268.  
  269. function mds_get_dc_elements($mdo)  // no record: FALSE
  270. {
  271.     if (!($mdt $this->mds_get($mdo->mdo_eid))) return FALSE;
  272.     
  273.     $xmlDoc new xmddoc(explode("\n"$mdt))if ($xmlDoc->errorreturn FALSE;
  274.     
  275.     $result array();
  276.     foreach ($mdo->mdo_dcmap_v as $dce => $xp)
  277.     {
  278.         $result[$dce$xmlDoc->xmd_value($xp);
  279.     }
  280.     
  281.     return $result;
  282. }
  283.  
  284. function mds_get_many($columns$where_clause)
  285. {
  286.     $cols '';
  287.     foreach (explode(','$columnsas $col$cols .= "," trim($col);
  288.     if (!$colsreturn;
  289.     
  290.     return $this->_query("SELECT " substr($cols1
  291.         " FROM " MDS_TABLE " WHERE "$where_clause);
  292. }
  293.  
  294. function mds_put($eid$data$column 'mdxmltext'$exists TRUE)
  295. {
  296.     if ($exists === TRUE)
  297.         return $this->_query("UPDATE " MDS_TABLE " SET " 
  298.             $this->_coldat($column$data" WHERE "$eid);
  299.     elseif ($exists === FALSE)
  300.         return $this->_query("INSERT INTO " MDS_TABLE " SET " 
  301.             $this->_coldat($column$data", "$eid);
  302.     else  // user doesn't know, check first whether the record exists
  303.         return $this->mds_put($eid$data$column
  304.             !($this->mds_get($eid=== FALSE));
  305. }
  306.  
  307. function mds_put_dc_elements($mdo$dcelem)
  308. {
  309.     if (($mdt $this->mds_get($mdo->mdo_eid)) === FALSE)
  310.     {
  311.         $mdt $mdo->mdo_generate_default_xml_metadata()$exists FALSE;
  312.     }
  313.     else $exists TRUE;
  314.     
  315.     $xmlDoc new xmddoc(explode("\n"$mdt))if ($xmlDoc->errorreturn FALSE;
  316.     
  317.     foreach ($dcelem as $dce => $value)
  318.     {
  319.         $xmlDoc->xmd_update($mdo->mdo_dcmap_v[$dce](string) $value);
  320.     }
  321.     
  322.     $this->mds_put($mdo->mdo_eid'''md5'$exists);
  323.     
  324.     return $this->mds_put($mdo->mdo_eid$xmlDoc->xmd_xml());
  325. }
  326.  
  327. function mds_append($eid$moredata$column 'indexabletext')
  328. {
  329.     if (($olddata $this->mds_get($eid$column)) === FALSEreturn FALSE;
  330.     $this->mds_put($eid$olddata $moredata$column)return $olddata;
  331. }
  332.  
  333. function mds_delete($eid)
  334. {
  335.     return $this->_query("DELETE FROM " MDS_TABLE " WHERE "$eid);
  336. }
  337.  
  338. function mds_delete_offspring($eid$sep '.')
  339. {
  340.     return $this->_query("DELETE FROM " MDS_TABLE " WHERE "$eid$sep);
  341. }
  342.  
  343. function mds_delete_many($idarray)
  344. {
  345.     if (!is_array($idarray|| count($idarray== 0return FALSE;
  346.     
  347.     return $this->_query("DELETE FROM " MDS_TABLE " WHERE eid IN ('" 
  348.         implode("','"array_map('addslashes'$idarray)) "')");
  349. }
  350.  
  351. function mds_update_xml_and_mdt($mdo&$xmlDoc$mda$eid&$traceinfo
  352.         $exists TRUE)  // note: $xmlDoc and $traceinfo passed by reference
  353. {
  354.     foreach (explode("\n"
  355.            str_replace("\r""\n"str_replace("\r\n""\n"$mda))) as $update)
  356.     {
  357.         if (!$updatecontinue;
  358.         
  359.         if (($nameLth strpos($update'=')))  // e.g. 'gen/tit/str=new'
  360.         {
  361.             if (($text substr($update$nameLth 1)) === FALSE$text '';
  362.             
  363.             if (!($path trim(substr($update0$nameLth)))) continue;
  364.             
  365.             if (($sc strpos($path';')))  // e.g. 'gen/tit,gen/des;str@lang'
  366.                 $xmlDoc->xmd_update_many(substr($path0$sc)
  367.                     substr($path$sc 1)$text);
  368.             else
  369.                 $xmlDoc->xmd_update($path$text);
  370.         }
  371.         elseif ($nameLth === FALSE)  // e.g. 'gen/tit/str[-1]~'
  372.         {
  373.             if ($update == '~~')
  374.             {
  375.                 $update 'DELETE ' $eid;
  376.                 if ($exists === FALSE$update '';
  377.                 else $this->mds_delete($eid);
  378.                 $mda ''$exists TRUE;
  379.                 foreach ($xmlDoc->children[0as $key => $child)
  380.                     unset($xmlDoc->children[0][$key]);
  381.             }
  382.             elseif ($update == '!!')
  383.             {
  384.                 define_kwds($mdo);
  385.                 $update ''$mda ''$exists TRUE;
  386.             }
  387.             else
  388.             {
  389.                 $x $xmlDoc->xmd_update(trim($update)'');
  390.             }
  391.         }
  392.         
  393.         if ($update$traceinfo .= $update '- ';
  394.     }
  395.     
  396.     $mdt $xmlDoc->xmd_xml();
  397.     
  398.     if ($exists === FALSE)
  399.     {
  400.         $this->mds_put($eid$mdt'mdxmltext'FALSE);
  401.         $traceinfo .= 'INSERT ' $eid '- ';
  402.     }
  403.     elseif($mda)
  404.     {
  405.         $this->mds_put($eid$mdt'mdxmltext');
  406.         $traceinfo .= 'UPDATE ' $eid '- ';
  407.     }
  408.     
  409.     return $mdt;
  410. }
  411.  
  412. function mdstore($allow_create)
  413. {
  414.     global $_courseif (!isset($_course)) return;
  415.     
  416.     define('MDS_TABLE'Database::get_course_table('metadata'));
  417.  
  418.     if (!api_sql_query("SELECT eid FROM " MDS_TABLE))
  419.     if ($allow_create)
  420.         $this->_query("CREATE TABLE " MDS_TABLE " (    " 
  421.                 "eid varchar(250) NOT NULL," .      // entry-id, e.g. doc.1
  422.                 "mdxmltext text default ''," .      // MD-text, XML-formatted
  423.                 "md5 char(32) default ''," .        // hash-validator
  424.                 "htmlcache1 text default ''," .     // cached HTML, part 1
  425.                 "htmlcache2 text default ''," .     // cached HTML, part 2
  426.                 "indexabletext text default ''," .  // indexable for search
  427.                 "PRIMARY KEY (eid)           )");
  428.     else give_up('No metadata store is available for this course.');
  429. }
  430.  
  431. function _coldatstart($column$data)
  432. {
  433.     return $column " LIKE '" addslashes($data"%'";
  434. }
  435.  
  436. function _coldat($column$data)
  437. {
  438.     return $column "='" addslashes($data"'";
  439. }
  440.  
  441. function _query($sql$eid ''$sep '')
  442. {
  443.     if ($eid$sql .= $sep $this->_coldatstart('eid'$eid $sep:
  444.         $this->_coldat('eid'$eid);
  445.     
  446.     return api_sql_query($sql__FILE____LINE__);
  447. }
  448.  
  449. }
  450.  
  451. /*
  452. <!--
  453.     This program is free software; you can redistribute it and/or
  454.     modify it under the terms of the GNU General Public License
  455.     as published by the Free Software Foundation; either version 2
  456.     of the License, or (at your option) any later version.
  457.     
  458.     This program is distributed in the hope that it will be useful,
  459.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  460.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  461.     GNU General Public License for more details.
  462.  
  463.   -->
  464. */
  465.  
  466. ?>

Documentation generated on Thu, 12 Jun 2008 14:05:44 -0500 by phpDocumentor 1.4.1