You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

523 lines
28 KiB

  1. <?php
  2. // Project: Web Reference Database (refbase) <http://www.refbase.net>
  3. // Copyright: Matthias Steffens <mailto:refbase@extracts.de> and the file's
  4. // original author(s).
  5. //
  6. // This code is distributed in the hope that it will be useful,
  7. // but WITHOUT ANY WARRANTY. Please see the GNU General Public
  8. // License for more details.
  9. //
  10. // File: ./includes/odfxml.inc.php
  11. // Repository: $HeadURL: file:///svn/p/refbase/code/branches/bleeding-edge/includes/odfxml.inc.php $
  12. // Author(s): Matthias Steffens <mailto:refbase@extracts.de>
  13. //
  14. // Created: 01-Jun-06, 12:49
  15. // Modified: $Date: 2017-04-13 02:00:18 +0000 (Thu, 13 Apr 2017) $
  16. // $Author: karnesky $
  17. // $Revision: 1416 $
  18. // This include file contains functions that'll export records to ODF XML
  19. // in spreadsheet format ('.ods').
  20. // Requires ActiveLink PHP XML Package, which is available under the GPL from:
  21. // <http://www.active-link.com/software/>
  22. // Incorporate some include files:
  23. include_once 'includes/webservice.inc.php'; // include functions that are commonly used with the refbase webservices
  24. include_once 'includes/transtab_refbase_unicode.inc.php'; // include refbase markup -> Unicode search & replace patterns
  25. include_once 'includes/zip.inc.php';
  26. // Import the ActiveLink Packages
  27. require_once("classes/include.php");
  28. import("org.active-link.xml.XML");
  29. import("org.active-link.xml.XMLDocument");
  30. // --------------------------------------------------------------------
  31. // Generates an ODF XML document
  32. function odfDocument($result, $odfBodyContentType)
  33. {
  34. global $contentTypeCharset; // these variables are defined in 'ini.inc.php'
  35. global $convertExportDataToUTF8;
  36. $odfDocumentDoc = new XMLDocument();
  37. if (($convertExportDataToUTF8 == "yes") AND ($contentTypeCharset != "UTF-8"))
  38. $odfDocumentDoc->setEncoding("UTF-8");
  39. else
  40. $odfDocumentDoc->setEncoding($contentTypeCharset);
  41. // Setup root element:
  42. $odfDocument = new XML("office:document-content");
  43. $rootAttributesArray = array(
  44. "xmlns:office" => "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
  45. "xmlns:style" => "urn:oasis:names:tc:opendocument:xmlns:style:1.0",
  46. "xmlns:text" => "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
  47. "xmlns:table" => "urn:oasis:names:tc:opendocument:xmlns:table:1.0",
  48. "xmlns:draw" => "urn:urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",
  49. "xmlns:fo" => "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",
  50. "xmlns:xlink" => "http://www.w3.org/1999/xlink",
  51. "xmlns:dc" => "http://purl.org/dc/elements/1.1/",
  52. "xmlns:meta" => "urn:oasis:names:tc:opendocument:xmlns:meta:1.0",
  53. "xmlns:number" => "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0",
  54. "xmlns:svg" => "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",
  55. "xmlns:chart" => "urn:oasis:names:tc:opendocument:xmlns:chart:1.0",
  56. "xmlns:dr3d" => "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0",
  57. "xmlns:math" => "http://www.w3.org/1998/Math/MathML",
  58. "xmlns:form" => "urn:oasis:names:tc:opendocument:xmlns:form:1.0",
  59. "xmlns:script" => "urn:oasis:names:tc:opendocument:xmlns:script:1.0",
  60. "xmlns:ooo" => "http://openoffice.org/2004/office",
  61. "xmlns:ooow" => "http://openoffice.org/2004/writer",
  62. "xmlns:oooc" => "http://openoffice.org/2004/calc",
  63. "xmlns:dom" => "http://www.w3.org/2001/xml-events",
  64. "xmlns:xforms" => "http://www.w3.org/2002/xforms",
  65. "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
  66. "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
  67. "office:version" => "1.0"
  68. );
  69. foreach ($rootAttributesArray as $attributeKey => $attributeValue)
  70. $odfDocument->setTagAttribute($attributeKey, $attributeValue);
  71. // Add common attributes:
  72. addNewBranch($odfDocument, "office-document-common-attrs", array(), ""); // function 'addNewBranch()' is defined in 'webservice.inc.php'
  73. // Add scripts:
  74. addNewBranch($odfDocument, "office:scripts", array(), "");
  75. // Add font face declarations:
  76. $odfDocumentFontFaceDcls = new XMLBranch("office:font-face-decls");
  77. addNewBranch($odfDocumentFontFaceDcls, "style:font-face", array("style:name" => "Arial1", "svg:font-family" => "Arial", "style:font-pitch" => "variable"), "");
  78. addNewBranch($odfDocumentFontFaceDcls, "style:font-face", array("style:name" => "Lucidasans", "svg:font-family" => "Lucidasans", "style:font-pitch" => "variable"), "");
  79. addNewBranch($odfDocumentFontFaceDcls, "style:font-face", array("style:name" => "Arial", "svg:font-family" => "Arial", "style:font-family-generic" => "swiss", "style:font-pitch" => "variable"), "");
  80. $odfDocument->addXMLBranch($odfDocumentFontFaceDcls);
  81. // Add automatic styles:
  82. if ($odfBodyContentType == "spreadsheet") // Define spreadsheet styles:
  83. {
  84. $odfDocumentAutoStyles = new XMLBranch("office:automatic-styles");
  85. // Define table style:
  86. $odfDocumentStyle = new XMLBranch("style:style");
  87. $odfDocumentStyle->setTagAttribute("style:name", "ta1");
  88. $odfDocumentStyle->setTagAttribute("style:family", "table");
  89. $odfDocumentStyle->setTagAttribute("style:master-page-name", "Default");
  90. addNewBranch($odfDocumentStyle, "style:table-properties", array("table:display" => "true", "style:writing-mode" => "lr-tb"), "");
  91. $odfDocumentAutoStyles->addXMLBranch($odfDocumentStyle);
  92. // Define style for first table row:
  93. $odfDocumentStyle = new XMLBranch("style:style");
  94. $odfDocumentStyle->setTagAttribute("style:name", "ro1");
  95. $odfDocumentStyle->setTagAttribute("style:family", "table-row");
  96. addNewBranch($odfDocumentStyle, "style:table-row-properties", array("style:row-height" => "0.1681in", "fo:break-before" => "auto", "style:use-optimal-row-height" => "true"), "");
  97. $odfDocumentAutoStyles->addXMLBranch($odfDocumentStyle);
  98. // Define style for all other table rows:
  99. $odfDocumentStyle = new XMLBranch("style:style");
  100. $odfDocumentStyle->setTagAttribute("style:name", "ro2");
  101. $odfDocumentStyle->setTagAttribute("style:family", "table-row");
  102. addNewBranch($odfDocumentStyle, "style:table-row-properties", array("style:row-height" => "0.6425in", "fo:break-before" => "auto", "style:use-optimal-row-height" => "true"), "");
  103. $odfDocumentAutoStyles->addXMLBranch($odfDocumentStyle);
  104. $odfDocument->addXMLBranch($odfDocumentAutoStyles);
  105. }
  106. // Add body:
  107. $odfDocumentBody = new XMLBranch("office:body");
  108. if ($odfBodyContentType == "spreadsheet") // generate ODF spreadsheet data
  109. {
  110. $odfSpreadsheet = odfSpreadsheet($result);
  111. $odfDocumentBody->addXMLasBranch($odfSpreadsheet);
  112. }
  113. $odfDocument->addXMLBranch($odfDocumentBody);
  114. $odfDocumentDoc->setXML($odfDocument);
  115. $odfDocumentString = $odfDocumentDoc->getXMLString();
  116. return $odfDocumentString;
  117. }
  118. // --------------------------------------------------------------------
  119. // Generates ODF spreadsheet XML
  120. function odfSpreadsheet($result)
  121. {
  122. global $citeKeysArray; // '$citeKeysArray' is made globally available from within this function
  123. $exportArray = array(); // array for individually exported records
  124. $citeKeysArray = array(); // array of cite keys (used to ensure uniqueness of cite keys among all exported records)
  125. // Map ODF indexes to refbase field names, map ODF reference types to refbase types and define search & replace patterns:
  126. list($universalSearchReplaceActionsArray, $fieldSpecificSearchReplaceActionsArray, $odfIndexesToRefbaseFieldsArray, $referenceTypesToRefbaseTypesArray) = initializeArrays();
  127. // Generate the export for each record and push them onto an array:
  128. while ($row = @ mysqli_fetch_array($result))
  129. {
  130. // Parse the current record into an array of field data that shall be exported to ODF:
  131. $recordExportArray = parseRecord($row, $odfIndexesToRefbaseFieldsArray, $referenceTypesToRefbaseTypesArray, $universalSearchReplaceActionsArray, $fieldSpecificSearchReplaceActionsArray);
  132. // Export the current record as ODF XML in a spreadsheet table row:
  133. $record = odfSpreadsheetTableRow($recordExportArray, "data");
  134. if (!empty($record)) // unless the record buffer is empty...
  135. array_push($exportArray, $record); // ...add it to an array of exports
  136. }
  137. $odfSpreadsheet = new XML("office:spreadsheet");
  138. $odfSpreadsheetTable = new XMLBranch("table:table");
  139. $odfSpreadsheetTable->setTagAttribute("table:name", "biblio");
  140. $odfSpreadsheetTable->setTagAttribute("table:style-name", "ta1");
  141. $columnHeadings = odfSpreadsheetTableRow($odfIndexesToRefbaseFieldsArray, "heading"); // export column headings as ODF XML in a spreadsheet table row
  142. $odfSpreadsheetTable->addXMLasBranch($columnHeadings);
  143. foreach ($exportArray as $tableRowXML)
  144. $odfSpreadsheetTable->addXMLasBranch($tableRowXML);
  145. $odfSpreadsheet->addXMLBranch($odfSpreadsheetTable);
  146. return $odfSpreadsheet;
  147. }
  148. // --------------------------------------------------------------------
  149. // Returns an XML table-row object of a single record
  150. function odfSpreadsheetTableRow($recordExportArray, $rowType)
  151. {
  152. // create an XML object for a single record
  153. $record = new XML("table:table-row");
  154. if ($rowType == "heading")
  155. {
  156. $record->setTagAttribute("table:style-name", "ro1");
  157. foreach ($recordExportArray as $odfIndex => $indexValue)
  158. {
  159. $tableCell = new XMLBranch("table:table-cell");
  160. $tableCell->setTagAttribute("office:value-type", "string");
  161. $tableCell->setTagContent($odfIndex, "table:table-cell/text:p");
  162. $record->addXMLBranch($tableCell);
  163. }
  164. }
  165. else // $rowType = "data"
  166. {
  167. $record->setTagAttribute("table:style-name", "ro2");
  168. foreach ($recordExportArray as $odfIndex => $indexValue)
  169. {
  170. $tableCell = new XMLBranch("table:table-cell");
  171. if (!empty($indexValue))
  172. {
  173. $tableCell->setTagAttribute("office:value-type", "string");
  174. $tableCell->setTagContent($indexValue, "table:table-cell/text:p");
  175. }
  176. $record->addXMLBranch($tableCell);
  177. }
  178. }
  179. return $record;
  180. }
  181. // --------------------------------------------------------------------
  182. // Parse a refbase record into an array of field data that shall be exported to ODF:
  183. function parseRecord($row, $odfIndexesToRefbaseFieldsArray, $referenceTypesToRefbaseTypesArray, $universalSearchReplaceActionsArray, $fieldSpecificSearchReplaceActionsArray)
  184. {
  185. global $officialDatabaseName; // these variables are defined in 'ini.inc.php'
  186. global $databaseBaseURL;
  187. global $contentTypeCharset;
  188. global $convertExportDataToUTF8;
  189. $fieldParametersArray = array();
  190. // this is a stupid hack that maps the names of the '$row' array keys to those used
  191. // by the '$formVars' array (which is required by function 'generateCiteKey()')
  192. // (eventually, the '$formVars' array should use the MySQL field names as names for its array keys)
  193. $formVars = buildFormVarsArray($row); // function 'buildFormVarsArray()' is defined in 'include.inc.php'
  194. // generate or extract the cite key for this record
  195. $citeKey = generateCiteKey($formVars); // function 'generateCiteKey()' is defined in 'include.inc.php'
  196. // PARSE RECORD:
  197. // parse the '$odfIndexesToRefbaseFieldsArray' which maps ODF indexes to refbase field names and assign fields accordingly:
  198. foreach ($odfIndexesToRefbaseFieldsArray as $odfIndex => $refbaseField)
  199. {
  200. if (empty($odfIndexesToRefbaseFieldsArray[$odfIndex]))
  201. {
  202. $fieldParametersArray[$odfIndex] = ""; // for any unsupported ODF index we'll insert an empty string
  203. }
  204. else
  205. {
  206. // copy row field data to array of field parameters (using the corresponding ODF index name as element key):
  207. if(!is_array($odfIndexesToRefbaseFieldsArray[$odfIndex]))
  208. {
  209. if (!empty($refbaseField) AND !empty($row[$refbaseField]))
  210. $fieldParametersArray[$odfIndex] = $row[$refbaseField];
  211. }
  212. else // if the current index's value in '$odfIndexesToRefbaseFieldsArray' is an array...
  213. {
  214. $useDefault = true;
  215. // ...we'll extract field data from different refbase fields depending on the current record's reference type:
  216. foreach ($odfIndexesToRefbaseFieldsArray[$odfIndex] as $referenceType => $refbaseField)
  217. if (($row['type'] == $referenceType))
  218. {
  219. $useDefault = false;
  220. if (is_array($odfIndexesToRefbaseFieldsArray[$odfIndex][$referenceType]))
  221. {
  222. foreach ($odfIndexesToRefbaseFieldsArray[$odfIndex][$referenceType] as $refbaseField)
  223. if (!empty($refbaseField) AND !empty($row[$refbaseField]))
  224. {
  225. $fieldParametersArray[$odfIndex] = $row[$refbaseField];
  226. break;
  227. }
  228. }
  229. elseif (!empty($refbaseField) AND !empty($row[$refbaseField]))
  230. {
  231. $fieldParametersArray[$odfIndex] = $row[$refbaseField];
  232. }
  233. break;
  234. }
  235. // 'Other' is used as default for all refbase types that were NOT explicitly specified:
  236. if ($useDefault AND !isset($fieldParametersArray[$odfIndex]) AND isset($odfIndexesToRefbaseFieldsArray[$odfIndex]['Other']))
  237. {
  238. if (is_array($odfIndexesToRefbaseFieldsArray[$odfIndex]['Other']))
  239. {
  240. foreach ($odfIndexesToRefbaseFieldsArray[$odfIndex]['Other'] as $refbaseField)
  241. if (!empty($refbaseField) AND !empty($row[$refbaseField]))
  242. {
  243. $fieldParametersArray[$odfIndex] = $row[$refbaseField];
  244. break;
  245. }
  246. }
  247. elseif (!empty($odfIndexesToRefbaseFieldsArray[$odfIndex]['Other']) AND !empty($row[$odfIndexesToRefbaseFieldsArray[$odfIndex]['Other']]))
  248. $fieldParametersArray[$odfIndex] = $row[$odfIndexesToRefbaseFieldsArray[$odfIndex]['Other']];
  249. }
  250. // if this ODF field is still not set, 'Any' is used as default, no matter whether any refbase types were specified explicitly or not:
  251. if (!isset($fieldParametersArray[$odfIndex]) AND isset($odfIndexesToRefbaseFieldsArray[$odfIndex]['Any']))
  252. {
  253. if (is_array($odfIndexesToRefbaseFieldsArray[$odfIndex]['Any']))
  254. {
  255. foreach ($odfIndexesToRefbaseFieldsArray[$odfIndex]['Any'] as $refbaseField)
  256. if (!empty($refbaseField) AND !empty($row[$refbaseField]))
  257. {
  258. $fieldParametersArray[$odfIndex] = $row[$refbaseField];
  259. break;
  260. }
  261. }
  262. elseif (!empty($odfIndexesToRefbaseFieldsArray[$odfIndex]['Any']) AND !empty($row[$odfIndexesToRefbaseFieldsArray[$odfIndex]['Any']]))
  263. $fieldParametersArray[$odfIndex] = $row[$odfIndexesToRefbaseFieldsArray[$odfIndex]['Any']];
  264. }
  265. }
  266. // if this ODF field isn't set yet, provide an empty string:
  267. if (!isset($fieldParametersArray[$odfIndex]))
  268. $fieldParametersArray[$odfIndex] = "";
  269. }
  270. }
  271. // POST-PROCESS FIELD DATA:
  272. // currently, we'll always overwrite the record serial in the 'Identifier' field with the generated cite key:
  273. // (this means that NO identifier will be exported if you've unchecked the export option "Include cite keys on export")
  274. $fieldParametersArray['Identifier'] = $citeKey;
  275. // convert refbase type names into ODF type numbers:
  276. $fieldParametersArray['BibliographyType'] = $referenceTypesToRefbaseTypesArray[$fieldParametersArray['BibliographyType']];
  277. // for theses, set the correct ODF type:
  278. if (!empty($row['thesis']))
  279. {
  280. if (($row['thesis'] == "Ph.D. thesis") OR ($row['thesis'] == "Doctoral thesis"))
  281. $fieldParametersArray['BibliographyType'] = "11"; // Dissertation
  282. else
  283. $fieldParametersArray['BibliographyType'] = "9"; // Thesis
  284. if (isset($fieldParametersArray['Annote']))
  285. $fieldParametersArray['Annote'] .= "; " . $row['thesis']; // append type of thesis to ODF 'Annote' field
  286. else
  287. $fieldParametersArray['Annote'] = $row['thesis'];
  288. }
  289. // if a DOI was copied to the URL field, we'll need to add the DOI resolver:
  290. if (!empty($row['doi']) AND preg_match("/^\d{2}\.\d{4}\//", $fieldParametersArray['URL']))
  291. $fieldParametersArray['URL'] = "http://dx.doi.org/" . $fieldParametersArray['URL'];
  292. // use the series volume as volume if 'series_volume' contains some info, but 'volume' doesn't:
  293. if (empty($row['volume']) AND !empty($row['series_volume']))
  294. $fieldParametersArray['Volume'] = $row['series_volume'];
  295. // set the fourth ODF custom field to a refbase database attribution string and the database URL:
  296. $fieldParametersArray['Custom4'] = "exported from " . $officialDatabaseName . " (" . $databaseBaseURL . ")";
  297. // set the fifth ODF custom field to the record's permanent database URL:
  298. $fieldParametersArray['Custom5'] = $databaseBaseURL . "show.php?record=" . $row['serial'];
  299. // apply universal search & replace actions, encode special chars and charset conversions to every field that shall be exported:
  300. foreach ($fieldParametersArray as $fieldName => $fieldValue)
  301. if (!empty($fieldValue))
  302. {
  303. // perform universal search & replace actions:
  304. if (!empty($universalSearchReplaceActionsArray))
  305. $fieldParametersArray[$fieldName] = searchReplaceText($universalSearchReplaceActionsArray, $fieldParametersArray[$fieldName], true); // function 'searchReplaceText()' is defined in 'include.inc.php'
  306. // we only convert those special chars to entities which are supported by XML:
  307. $fieldParametersArray[$fieldName] = encodeHTMLspecialchars($fieldParametersArray[$fieldName]); // function 'encodeHTMLspecialchars()' is defined in 'include.inc.php'
  308. // convert field data to UTF-8 (if '$convertExportDataToUTF8' is set to "yes" in 'ini.inc.php' and character encoding is not UTF-8 already):
  309. // (note that charset conversion can only be done *after* the cite key has been generated, otherwise cite key generation will produce garbled text!)
  310. if (($convertExportDataToUTF8 == "yes") AND ($contentTypeCharset != "UTF-8"))
  311. $fieldParametersArray[$fieldName] = convertToCharacterEncoding("UTF-8", "IGNORE", $fieldParametersArray[$fieldName]); // function 'convertToCharacterEncoding()' is defined in 'include.inc.php'
  312. }
  313. // apply field-specific search & replace 'actions' to all fields that are listed in the 'fields' element of the arrays contained in '$fieldSpecificSearchReplaceActionsArray':
  314. foreach ($fieldSpecificSearchReplaceActionsArray as $fieldActionsArray)
  315. foreach ($fieldParametersArray as $fieldName => $fieldValue)
  316. if (in_array($fieldName, $fieldActionsArray['fields']))
  317. $fieldParametersArray[$fieldName] = searchReplaceText($fieldActionsArray['actions'], $fieldValue, true); // function 'searchReplaceText()' is defined in 'include.inc.php'
  318. return $fieldParametersArray;
  319. }
  320. // --------------------------------------------------------------------
  321. // Map ODF indexes to refbase field names, map ODF reference types to refbase types and define search & replace patterns:
  322. function initializeArrays()
  323. {
  324. global $convertExportDataToUTF8; // defined in 'ini.inc.php'
  325. // The array '$transtab_refbase_unicode' contains search & replace patterns for conversion from refbase markup to Unicode entities.
  326. global $transtab_refbase_unicode; // defined in 'transtab_refbase_unicode.inc.php'
  327. // Defines universal search & replace actions:
  328. // (Note that the order of array elements IS important since it defines when a search/replace action gets executed)
  329. // (If you don't want to perform any search and replace actions, specify an empty array, like: '$universalSearchReplaceActionsArray = array();'.
  330. // Note that the search patterns MUST include the leading & trailing slashes -- which is done to allow for mode modifiers such as 'imsxU'.)
  331. // "/Search Pattern/" => "Replace Pattern"
  332. $universalSearchReplaceActionsArray = array(); // example: 'array("/&/" => "&amp;", "/</" => "&lt;");'
  333. // Defines field-specific search & replace 'actions' that will be applied to all those ODF fields that are listed in the corresponding 'fields' element:
  334. // (If you don't want to perform any search and replace actions, specify an empty array, like: '$fieldSpecificSearchReplaceActionsArray = array();'.
  335. // Note that the search patterns MUST include the leading & trailing slashes -- which is done to allow for mode modifiers such as 'imsxU'.)
  336. // "/Search Pattern/" => "Replace Pattern"
  337. $fieldSpecificSearchReplaceActionsArray = array();
  338. if ($convertExportDataToUTF8 == "yes")
  339. $fieldSpecificSearchReplaceActionsArray[] = array(
  340. 'fields' => array("Author", "Title", "Booktitle", "Journal", "Organizations", "Custom1", "Series", "Pages", "Note"),
  341. 'actions' => $transtab_refbase_unicode
  342. );
  343. // Map ODF indexes to refbase field names:
  344. // Notes: - the special array key "Other" serves as a default for all refbase types that were NOT specified explicitly
  345. // - the special array key "Any" serves as a default for all refbase types
  346. // - instead of specifying a string with a single refbase field name, you can also give a sub-array of multiple refbase field names
  347. // where the first non-empty field will be taken as ODF field value
  348. // "ODF index name" => "refbase field name" // ODF index description (comment)
  349. $odfIndexesToRefbaseFieldsArray = array(
  350. "Identifier" => "serial", // a unique identifier for the bibliographic data (the 'parseRecord()' function will overwrite the record serial with a correct cite key if necessary)
  351. "BibliographyType" => "type", // the type of the bibliographic reference. It is of the type bibliographydatafield
  352. "Address" => "place", // the address of the publisher
  353. "Annote" => "notes", // an annotation
  354. "Author" => "author", // the name(s) of the author(s)
  355. "Booktitle" => array("Book Chapter" => "publication"), // the title of the book
  356. "Chapter" => array("Book Chapter" => "volume"), // name or number of the chapter
  357. "Edition" => "edition", // the number or name of the edition
  358. "Editor" => "editor", // the name(s) of the editor(s)
  359. "Howpublished" => "", // a description of the type of the publishing
  360. "Institution" => "", // the name of the institution where the publishing was created
  361. "Journal" => array("Journal Article" => array("publication", "abbrev_journal")), // the name of the journal
  362. "Month" => "", // number or name of the month of the publishing
  363. "Note" => "user_notes", // a note
  364. "Number" => "issue", // the number of the publishing
  365. "Organizations" => "address", // the name of the organizations where the publishing was created
  366. "Pages" => "pages", // the number(s) of the page(s) of the reference into a publishing
  367. "Publisher" => "publisher", // the name of the publisher
  368. "School" => "corporate_author", // the name of the university or school where the publishing was created
  369. "Series" => array("Any" => array("series_title", "abbrev_series_title")), // the series of the publishing
  370. "Title" => "title", // the title of the publishing
  371. "ReportType" => "", // a description of the type of the report
  372. "Volume" => "volume", // the volume of the publishing
  373. "Year" => "year", // the year when the publishing was created
  374. "URL" => array("Any" => array("doi", "url")), // URL of the publishing (in case of a DOI, the 'parseRecord()' function will prefix it with a DOI resolver)
  375. "ISBN" => "isbn", // the ISBN data of the publishing
  376. "Custom1" => "keywords", // user defined data
  377. "Custom2" => "user_keys", // user defined data
  378. "Custom3" => "user_groups", // user defined data
  379. "Custom4" => "", // user defined data (this field will be set to the database name and URL in function 'parseRecord()')
  380. "Custom5" => "" // user defined data (this field will be set to the record's permanent URL in function 'parseRecord()')
  381. );
  382. // This array matches ODF reference types with their corresponding refbase types:
  383. // ODF types which are currently not supported by refbase are commented out;
  384. // '#fallback#' in comments indicates a type mapping that is not a perfect match but as close as currently possible)
  385. // "refbase type" => "ODF type" // display name of ODF reference type (comment)
  386. $referenceTypesToRefbaseTypesArray = array(
  387. // "Journal Article" => "0", // Article (#fallback#; correct?)
  388. "Book Whole" => "1", // Book
  389. // "Book Whole" => "2", // Brochures (#fallback#)
  390. // "Book Whole" => "3", // Conference proceeding (correct? conference?)
  391. // "Book Chapter" => "4", // Book excerpt (#fallback#)
  392. "Book Chapter" => "5", // Book excerpt with title
  393. "Conference Article" => "6", // Conference proceeding (correct? inproceedings?)
  394. "Journal Article" => "7", // Journal (AFAIK, 'Journal' means a journal article and not a whole journal)
  395. "Manual" => "8", // Tech. Documentation (#fallback#)
  396. // "Book Whole" => "9", // Thesis (#fallback#; function 'parseRecord()' will set the ODF type to 'Thesis' if the refbase 'thesis' field isn't empty)
  397. "Miscellaneous" => "10", // Miscellaneous
  398. // "Book Whole" => "11", // Dissertation (#fallback#; function 'parseRecord()' will set the ODF type to 'Dissertation' if the refbase 'thesis' field contains either 'Ph.D. thesis' or 'Doctoral thesis'))
  399. "Conference Volume" => "12", // Conference proceeding (correct? proceedings?)
  400. "Report" => "13", // Research report (#fallback#)
  401. "Manuscript" => "14", // Unpublished (#fallback#)
  402. // "" => "15", // e-mail (currently not supported by refbase)
  403. // "" => "16", // WWW document (currently not supported by refbase)
  404. "Newspaper Article" => "17", // User-defined1
  405. "Magazine Article" => "18", // User-defined2
  406. "Patent" => "19", // User-defined3
  407. "Software" => "20", // User-defined4
  408. "Map" => "21" // User-defined5
  409. // "Abstract" => "" // could we specify more than 21 ODF types?
  410. // "Journal" => ""
  411. );
  412. return array($universalSearchReplaceActionsArray, $fieldSpecificSearchReplaceActionsArray, $odfIndexesToRefbaseFieldsArray, $referenceTypesToRefbaseTypesArray);
  413. }
  414. // --------------------------------------------------------------------
  415. // Encloses the ODF XML document given in '$content' with a minimal ODF file & directory
  416. // structure, and zips the generated directory of XML files as an ODF spreadsheet (ODS file)
  417. //
  418. // Author: Richard Karnesky <mailto:karnesky@gmail.com>
  419. function zipODF($content) {
  420. $zipfile = new zipfile();
  421. //$zipfile -> add_dir("META-INF/");
  422. $zipfile -> addFile($content, "content.xml"); // function 'addFile()' is defined in 'zip.inc.php'
  423. $zipfile -> addFile("", "styles.xml");
  424. $zipfile -> addFile("application/vnd.oasis.opendocument.spreadsheet","mimetype");
  425. $zipfile -> addFile("<?xml version=\"1.0\" encoding=\"UTF-8\"?><office:document-meta xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\" xmlns:ooo=\"http://openoffice.org/2004/office\" office:version=\"1.0\"><office:meta><meta:generator>refbase</meta:generator></office:meta></office:document-meta>","meta.xml");
  426. $zipfile -> addFile("<?xml version=\"1.0\" encoding=\"UTF-8\"?><manifest:manifest xmlns:manifest=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\"><manifest:file-entry manifest:media-type=\"application/vnd.oasis.opendocument.spreadsheet\" manifest:full-path=\"/\"/><manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"content.xml\"/><manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"styles.xml\"/><manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"meta.xml\"/></manifest:manifest>","META-INF/manifest.xml");
  427. return $zipfile;
  428. }
  429. // --------------------------------------------------------------------
  430. ?>