aboutsummaryrefslogtreecommitdiff
path: root/engine/lib/export.php
diff options
context:
space:
mode:
Diffstat (limited to 'engine/lib/export.php')
-rw-r--r--engine/lib/export.php422
1 files changed, 213 insertions, 209 deletions
diff --git a/engine/lib/export.php b/engine/lib/export.php
index 5937a71bc..ecc894e63 100644
--- a/engine/lib/export.php
+++ b/engine/lib/export.php
@@ -1,219 +1,223 @@
<?php
- /**
- * Elgg Data import export functionality.
- *
- * @package Elgg
- * @subpackage Core
- * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
- * @author Marcus Povey
- * @copyright Curverider Ltd 2008
- * @link http://elgg.org/
- */
-
- /**
- * Define an interface for all exportable objects.
- */
- interface Exportable
- {
- /**
- * This must take the contents of the object and return it as a stdClass.
- */
- public function export();
- }
+/**
+ * Elgg Data import export functionality.
+ *
+ * @package Elgg.Core
+ * @subpackage DataModel.Export
+ */
+
+/**
+ * Get a UUID from a given object.
+ *
+ * @param mixed $object The object either an ElggEntity, ElggRelationship or ElggExtender
+ *
+ * @return string|false the UUID or false
+ */
+function get_uuid_from_object($object) {
+ if ($object instanceof ElggEntity) {
+ return guid_to_uuid($object->guid);
+ } else if ($object instanceof ElggExtender) {
+ $type = $object->type;
+ if ($type == 'volatile') {
+ $uuid = guid_to_uuid($object->entity_guid) . $type . "/{$object->name}/";
+ } else {
+ $uuid = guid_to_uuid($object->entity_guid) . $type . "/{$object->id}/";
+ }
- /**
- * Export a GUID.
- *
- * This function exports a GUID and all information related to it in an XML format.
- *
- * This function makes use of the "serialise" plugin hook, which is passed an array to which plugins
- * should add data to be serialised to.
- *
- * @see ElggEntity for an example of its usage.
- * @param int $guid The GUID.
- * @return xml
- */
- function export($guid)
- {
- global $CONFIG;
-
- $guid = (int)$guid;
-
- // Initialise the array
- $to_be_serialised = array();
-
- // Trigger a hook to
- $to_be_serialised = trigger_plugin_hook("export", "all", array("guid" => $guid), $to_be_serialised);
-
- // Sanity check
- if (!is_array($to_be_serialised)) throw new ExportException("There was a problem during the serialisation of GUID:$guid");
-
- // Now serialise the result to XML
- $wrapper = new stdClass;
-
- // Construct header
- $wrapper->header = new stdClass;
- $wrapper->header->date = date("r");
- $wrapper->header->timestamp = time();
- $wrapper->header->domain = $CONFIG->wwwroot;
- $wrapper->header->guid = $guid;
- $wrapper->header->uuid = guid_to_uuid($guid);
- $wrapper->header->exported_by = guid_to_uuid($_SESSION['id']);
-
- // Construct data
- $wrapper->data = $to_be_serialised;
-
- return serialise_object_to_xml($wrapper, "elggexport");
-
-
- /*
- XML will look something like this:
-
-
- <elgg>
- <elgguser uuid="skdfjslklkjsldkfsdfjs:556">
- <guid>556</guid>
- <name>Marcus Povey</name>
-
- ...
-
- </elgguser>
- <annotation>
- <name>Foo</name>
- <value>baaaa</value>
- </annotation>
- <annotation>
- <name>Monkey</name>
- <value>bibble</value>
- </annotation>
-
- ...
-
- <metadata>
- <name>Foo</name>
- <value>baaaa</value>
- </metadata>
-
- ...
-
- <my_plugin>
-
- ...
-
- </my_plugin>
-
- </elgg>
-
- */
-
+ return $uuid;
+ } else if ($object instanceof ElggRelationship) {
+ return guid_to_uuid($object->guid_one) . "relationship/{$object->id}/";
}
-
- /**
- * Import an XML serialisation of an object.
- * This will make a best attempt at importing a given xml doc.
- *
- * @param string $xml
- * @return int The new GUID of the object.
- */
- function import($xml)
- {
- // import via object ?
-
- // import via tag : so you pass a tag "<foo>" and all its contents out and something answers by handling it.
- // THis is recursive but bredth first.
-
-
+
+ return false;
+}
+
+/**
+ * Generate a UUID from a given GUID.
+ *
+ * @param int $guid The GUID of an object.
+ *
+ * @return string
+ */
+function guid_to_uuid($guid) {
+ return elgg_get_site_url() . "export/opendd/$guid/";
+}
+
+/**
+ * Test to see if a given uuid is for this domain, returning true if so.
+ *
+ * @param string $uuid A unique ID
+ *
+ * @return bool
+ */
+function is_uuid_this_domain($uuid) {
+ if (strpos($uuid, elgg_get_site_url()) === 0) {
+ return true;
}
- /**
- * Generate a UUID from a given GUID.
- *
- * @param int $guid The GUID of an object.
- */
- function guid_to_uuid($guid)
- {
- global $CONFIG;
-
- return "UUID:".md5($CONFIG->wwwroot) . ":$guid";
+ return false;
+}
+
+/**
+ * This function attempts to retrieve a previously imported entity via its UUID.
+ *
+ * @param string $uuid A unique ID
+ *
+ * @return ElggEntity|false
+ */
+function get_entity_from_uuid($uuid) {
+ $uuid = sanitise_string($uuid);
+
+ $options = array('metadata_name' => 'import_uuid', 'metadata_value' => $uuid);
+ $entities = elgg_get_entities_from_metadata($options);
+
+ if ($entities) {
+ return $entities[0];
}
-
- /**
- * This function serialises an object recursively into an XML representation.
- * The function attempts to call $data->export() which expects a stdClass in return, otherwise it will attempt to
- * get the object variables using get_object_vars (which will only return public variables!)
- * @param $data object The object to serialise.
- * @param $n int Level, only used for recursion.
- * @return string The serialised XML output.
- */
- function serialise_object_to_xml($data, $name = "", $n = 0)
- {
- $classname = ($name=="" ? get_class($data) : $name);
-
- $vars = method_exists($data, "export") ? get_object_vars($data->export()) : get_object_vars($data);
-
- $output = "";
-
- if (($n==0) || ( is_object($data) && !($data instanceof stdClass))) $output = "<$classname>";
-
- foreach ($vars as $key => $value)
- {
- $output .= "<$key type=\"".gettype($value)."\">";
-
- if (is_object($value))
- $output .= serialise_object_to_xml($value, $key, $n+1);
- else if (is_array($value))
- $output .= serialise_array_to_xml($value, $n+1);
- else
- $output .= htmlentities($value);
-
- $output .= "</$key>\n";
+
+ return false;
+}
+
+/**
+ * Tag a previously created guid with the uuid it was imported on.
+ *
+ * @param int $guid A GUID
+ * @param string $uuid A Unique ID
+ *
+ * @return bool
+ */
+function add_uuid_to_guid($guid, $uuid) {
+ $guid = (int)$guid;
+ $uuid = sanitise_string($uuid);
+
+ $result = create_metadata($guid, "import_uuid", $uuid);
+ return (bool)$result;
+}
+
+
+$IMPORTED_DATA = array();
+$IMPORTED_OBJECT_COUNTER = 0;
+
+/**
+ * This function processes an element, passing elements to the plugin stack to see if someone will
+ * process it.
+ *
+ * If nobody processes the top level element, the sub level elements are processed.
+ *
+ * @param ODD $odd The odd element to process
+ *
+ * @return bool
+ * @access private
+ */
+function _process_element(ODD $odd) {
+ global $IMPORTED_DATA, $IMPORTED_OBJECT_COUNTER;
+
+ // See if anyone handles this element, return true if it is.
+ $to_be_serialised = null;
+ if ($odd) {
+ $handled = elgg_trigger_plugin_hook("import", "all", array("element" => $odd), $to_be_serialised);
+
+ // If not, then see if any of its sub elements are handled
+ if ($handled) {
+ // Increment validation counter
+ $IMPORTED_OBJECT_COUNTER ++;
+ // Return the constructed object
+ $IMPORTED_DATA[] = $handled;
+
+ return true;
}
-
- if (($n==0) || ( is_object($data) && !($data instanceof stdClass))) $output .= "</$classname>\n";
-
- return $output;
}
- /**
- * Serialise an array.
- *
- * @param array $data
- * @param int $n Used for recursion
- * @return string
- */
- function serialise_array_to_xml(array $data, $n = 0)
- {
- $output = "";
-
- if ($n==0) $output = "<array>\n";
-
- foreach ($data as $key => $value)
- {
- $item = "array_item";
-
- if (is_numeric($key))
- $output .= "<$item name=\"$key\" type=\"".gettype($value)."\">";
- else
- {
- $item = $key;
- $output .= "<$item type=\"".gettype($value)."\">";
- }
-
- if (is_object($value))
- $output .= serialise_object_to_xml($value, "", $n+1);
- else if (is_array($value))
- $output .= serialise_array_to_xml($value, $n+1);
- else
- $output .= htmlentities($value);
-
- $output .= "</$item>\n";
- }
-
- if ($n==0) $output = "</array>\n";
-
- return $output;
+ return false;
+}
+
+/**
+ * Exports an entity as an array
+ *
+ * @param int $guid Entity GUID
+ *
+ * @return array
+ * @throws ExportException
+ * @access private
+ */
+function exportAsArray($guid) {
+ $guid = (int)$guid;
+
+ // Trigger a hook to
+ $to_be_serialised = elgg_trigger_plugin_hook("export", "all", array("guid" => $guid), array());
+
+ // Sanity check
+ if ((!is_array($to_be_serialised)) || (count($to_be_serialised) == 0)) {
+ throw new ExportException(elgg_echo('ExportException:NoSuchEntity', array($guid)));
+ }
+
+ return $to_be_serialised;
+}
+
+/**
+ * Export a GUID.
+ *
+ * This function exports a GUID and all information related to it in an XML format.
+ *
+ * This function makes use of the "serialise" plugin hook, which is passed an array to which plugins
+ * should add data to be serialised to.
+ *
+ * @param int $guid The GUID.
+ *
+ * @return string XML
+ * @see ElggEntity for an example of its usage.
+ * @access private
+ */
+function export($guid) {
+ $odd = new ODDDocument(exportAsArray($guid));
+
+ return ODD_Export($odd);
+}
+
+/**
+ * Import an XML serialisation of an object.
+ * This will make a best attempt at importing a given xml doc.
+ *
+ * @param string $xml XML string
+ *
+ * @return bool
+ * @throws ImportException if there was a problem importing the data.
+ * @access private
+ */
+function import($xml) {
+ global $IMPORTED_DATA, $IMPORTED_OBJECT_COUNTER;
+
+ $IMPORTED_DATA = array();
+ $IMPORTED_OBJECT_COUNTER = 0;
+
+ $document = ODD_Import($xml);
+ if (!$document) {
+ throw new ImportException(elgg_echo('ImportException:NoODDElements'));
}
-
- class ExportException extends Exception {}
- class ImportException extends Exception {}
-?> \ No newline at end of file
+
+ foreach ($document as $element) {
+ _process_element($element);
+ }
+
+ if ($IMPORTED_OBJECT_COUNTER != count($IMPORTED_DATA)) {
+ throw new ImportException(elgg_echo('ImportException:NotAllImported'));
+ }
+
+ return true;
+}
+
+
+/**
+ * Register the OpenDD import action
+ *
+ * @return void
+ * @access private
+ */
+function export_init() {
+ global $CONFIG;
+
+ elgg_register_action("import/opendd");
+}
+
+// Register a startup event
+elgg_register_event_handler('init', 'system', 'export_init', 100);