diff options
Diffstat (limited to 'engine/lib/export.php')
| -rw-r--r-- | engine/lib/export.php | 422 |
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); |
