aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engine/lib/export.php169
1 files changed, 149 insertions, 20 deletions
diff --git a/engine/lib/export.php b/engine/lib/export.php
index 279d3e8a6..93c7dc129 100644
--- a/engine/lib/export.php
+++ b/engine/lib/export.php
@@ -61,12 +61,11 @@
class ImportException extends DataFormatException {}
/**
- * Open Data Definition (ODD) superclass.
- * @package Elgg
- * @subpackage Core
+ * @class ODDDocument ODD Document container.
+ * This class is used during import and export to construct.
* @author Marcus Povey
*/
- abstract class ODD
+ class ODDDocument
{
/**
* ODD Version
@@ -76,6 +75,88 @@
private $ODDSupportedVersion = "1.0";
/**
+ * Elements of the document.
+ */
+ private $elements;
+
+ public function __construct(array $elements = NULL)
+ {
+ if ($elements)
+ $this->elements = $elements;
+ else
+ $this->elements = array();
+ }
+
+ /**
+ * Return the version of ODD being used.
+ *
+ * @return string
+ */
+ public function getVersion() { return $this->ODDSupportedVersion; }
+
+ public function addElement(ODD $element) { $this->elements[] = $element; }
+ public function addElements(array $elements)
+ {
+ foreach ($elements as $element)
+ $this->addElement($element);
+ }
+
+ public function getElements() { return $this->elements; }
+
+ /**
+ * Magic function to generate valid ODD XML for this item.
+ */
+ public function __toString()
+ {
+ $xml = "";
+ $namespaces = "";
+ $elements_xml = "";
+
+ // Get XML and catalog namespaces
+ foreach ($this->elements as $element)
+ {
+ $elements_xml .= "$element";
+
+ // Lookup namespace and get prefix
+ $ns = $element->getNamespace();
+ if (($ns) && (strpos($namespaces, $ns)===false))
+ {
+ $prefix = register_odd_extension_namespace($ns); // cheating... will return a prefix no matter what.
+ $namespaces .= " xmlns:$prefix=\"$ns\"";
+ }
+ else
+ trigger_error("'".get_class($element)."' has no namespace attached.", E_USER_WARNING);
+ }
+
+ // Output begin tag
+ $generated = date("r");
+ $xml .= "<odd version=\"{$this->ODDSupportedVersion}\" generated=\"$generated\" $namespaces>\n";
+
+ // output elements
+ $xml .= $elements_xml;
+
+ // Output end tag
+ $xml .= "</odd>\n";
+
+ return $xml;
+ }
+ }
+
+
+ /**
+ * Open Data Definition (ODD) superclass.
+ * @package Elgg
+ * @subpackage Core
+ * @author Marcus Povey
+ */
+ abstract class ODD
+ {
+ /**
+ * Namespace defining the ODD extension being used, optional but highly recommended.
+ */
+ private $namespace;
+
+ /**
* Attributes.
*/
private $attributes = array();
@@ -103,13 +184,8 @@
}
public function setBody($value) { $this->body = $value; }
public function getBody() { return $this->body; }
-
- /**
- * Return the version of ODD being used.
- *
- * @return real
- */
- public function getVersion() { return $this->ODDSupportedVersion; }
+ public function setNamespace($namespace) { $this->namespace = $namespace; }
+ public function getNamespace() { return $this->namespace; }
/**
* For serialisation, implement to return a string name of the tag eg "header" or "metadata".
@@ -122,6 +198,11 @@
*/
public function __toString()
{
+ // Namespace mapping
+ $ns = "";
+ if ($this->getNamespace()!="")
+ $ns = register_odd_extension_namespace($this->getNamespace()) . ":"; // Short way: if it has been registered already we'll get back a prefix, if not it'll generate one and return.
+
// Construct attributes
$attr = "";
foreach ($this->attributes as $k => $v)
@@ -132,9 +213,9 @@
$end = "/>";
if ($body!="")
- $end = ">$body</$tag>";
+ $end = ">$body</{$ns}{$tag}>";
- return "<$tag $attr" . $end . "\n";
+ return "<{$ns}{$tag} $attr" . $end . "\n";
}
}
@@ -233,6 +314,59 @@
return $odd;
}
+ /** ODD Namespaces & registered extension **/
+ $ODD_EXTENSION_NAMESPACES = array();
+
+ /**
+ * This function registers a namespace prefix with a given extension.
+ * Use this function to register a friendly prefix against a namespace. Namespaces will
+ * still function if you don't use this function however this gives you the opportunity to
+ * register a more human readable name.
+ *
+ * @param string $extension_url The namespace URL as given in the extension spec.
+ * @param string $namespace_prefix The chosen prefix, if this is blank then one is generated.
+ * @return string The extension prefix to be used, either $namespace_prefix, an already registered prefix or a generated one.
+ */
+ function register_odd_extension_namespace($extension_url, $namespace_prefix = "")
+ {
+ global $ODD_EXTENSION_NAMESPACES;
+
+ if (isset($ODD_EXTENSION_NAMESPACES[$extension_url]))
+ return $ODD_EXTENSION_NAMESPACES[$extension_url];
+
+ if ($namespace_prefix == "")
+ {
+ do
+ {
+ $namespace_prefix = substr(strtolower(base64_encode(md5(mt_rand()))), 0, 8);
+ }
+ while (
+ (array_key_exists($namespace_prefix, $ODD_EXTENSION_NAMESPACES)) ||
+ (is_numeric($namespace_prefix[0]))
+ ); // TODO: Do this better, but i'm quite tired now...
+ }
+
+ $ODD_EXTENSION_NAMESPACES[$extension_url] = $namespace_prefix;
+
+ return $ODD_EXTENSION_NAMESPACES[$extension_url];
+ }
+
+ /**
+ * Get a named prefix.
+ *
+ * @param string $extension_url The namespace URL as given in the extension spec.
+ * @return mixed The prefix associated with the given extension or false;
+ */
+ function get_odd_namespace_prefix($extension_url)
+ {
+ global $ODD_EXTENSION_NAMESPACES;
+
+ if (isset($ODD_EXTENSION_NAMESPACES[$extension_url]))
+ return $ODD_EXTENSION_NAMESPACES[$extension_url];
+
+ return false;
+ }
+
/** Relationship verb mapping */
$ODD_RELATIONSHIP_VERBS = array();
@@ -401,14 +535,9 @@
// Sanity check
if ((!is_array($to_be_serialised)) || (count($to_be_serialised)==0)) throw new ExportException("No such entity GUID:$guid");
- $output = "<odd>\n";
-
- foreach ($to_be_serialised as $odd)
- $output .= "$odd";
-
- $output .= "</odd>\n";
+ $odd = new ODDDocument($to_be_serialised);
- return $output;
+ return "$odd";
}
/**