From: Tom Needham Date: Tue, 20 Mar 2012 20:19:21 +0000 (+0000) Subject: Added unified import method. X-Git-Tag: v4.0.0beta~404 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=514c9ad8e7df1d7882adc33c42eb32a209537273;p=nextcloud-server.git Added unified import method. --- diff --git a/apps/admin_export/settings.php b/apps/admin_export/settings.php index af8dd0dbf54..cd85bedcd7d 100644 --- a/apps/admin_export/settings.php +++ b/apps/admin_export/settings.php @@ -25,8 +25,6 @@ OC_Util::checkAdminUser(); OC_Util::checkAppEnabled('admin_export'); -define('DS', '/'); - // Export? if (isset($_POST['admin_export'])) { // Create the export zip @@ -44,9 +42,11 @@ if (isset($_POST['admin_export'])) { } // Import? } else if( isset($_POST['admin_import']) ){ - - // TODO - // OC_Migrate::import( $pathtozipfile ); + $from = $_FILES['owncloud_import']['tmp_name']; + + if( !OC_Migrate::import( $from ) ){ + die('failed'); + } } else { // fill template diff --git a/apps/bookmarks/lib/migrate.php b/apps/bookmarks/lib/migrate.php index 36a08c0cf40..02c96e59632 100644 --- a/apps/bookmarks/lib/migrate.php +++ b/apps/bookmarks/lib/migrate.php @@ -36,19 +36,19 @@ class OC_Migration_Provider_Bookmarks extends OC_Migration_Provider{ switch( $this->appinfo->version ){ default: // All versions of the app have had the same db structure, so all can use the same import function - $query = OC_Migrate::prepare( "SELECT * FROM bookmarks WHERE user_id LIKE ?" ); - $results = $query->execute( array( $this->info['olduid'] ) ); + $query = $this->content->prepare( "SELECT * FROM bookmarks WHERE user_id LIKE ?" ); + $results = $query->execute( array( $this->olduid ) ); $idmap = array(); - while( $row = $data->fetchRow() ){ + while( $row = $results->fetchRow() ){ // Import each bookmark, saving its id into the map $query = OC_DB::prepare( "INSERT INTO *PREFIX*bookmarks(url, title, user_id, public, added, lastmodified) VALUES (?, ?, ?, ?, ?, ?)" ); - $query->execute( array( $row['url'], $row['title'], $this->info['newuid'], $row['public'], $row['added'], $row['lastmodified'] ) ); + $query->execute( array( $row['url'], $row['title'], $this->uid, $row['public'], $row['added'], $row['lastmodified'] ) ); // Map the id $idmap[$row['id']] = OC_DB::insertid(); } // Now tags foreach($idmap as $oldid => $newid){ - $query = OC_Migrate::prepare( "SELECT * FROM bookmarks_tags WHERE user_id LIKE ?" ); + $query = $this->content->prepare( "SELECT * FROM bookmarks_tags WHERE user_id LIKE ?" ); $results = $query->execute( array( $oldid ) ); while( $row = $data->fetchRow() ){ // Import the tags for this bookmark, using the new bookmark id diff --git a/apps/user_migrate/admin.php b/apps/user_migrate/admin.php index 6f3565788eb..d54bd6965b5 100644 --- a/apps/user_migrate/admin.php +++ b/apps/user_migrate/admin.php @@ -36,24 +36,12 @@ if (isset($_POST['user_import'])) { $from = $_FILES['owncloud_import']['tmp_name']; $to = get_temp_dir().'/'.$importname.'.zip'; if( !move_uploaded_file( $from, $to ) ){ - OC_Log::write('migration',"Failed to copy the uploaded file",OC_Log::INFO); + OC_Log::write( 'user_migrate', "Failed to copy the uploaded file", OC_Log::ERROR ); exit(); } - // Extract zip - $zip = new ZipArchive(); - if ($zip->open(get_temp_dir().'/'.$importname.'.zip') != TRUE) { - OC_Log::write('migration',"Failed to open zip file",OC_Log::INFO); - exit(); - } - $zip->extractTo(get_temp_dir().'/'.$importname.'/'); - $zip->close(); - - $importdir = get_temp_dir() . '/' . $importname; - - // Delete uploaded file - unlink( $importdir . '.zip' ); - + OC_Migrate::import( $to, 'user', 'newuser' ); + die(); // Find folder $files = scandir( $importdir ); unset($files[0]); diff --git a/lib/db.php b/lib/db.php index 07e58590966..bfcff678699 100644 --- a/lib/db.php +++ b/lib/db.php @@ -487,6 +487,7 @@ class OC_DB { /** * @breif replaces the owncloud tables with a new set + * @param $file string path to the MDB2 xml db export file */ public static function replaceDB( $file ){ @@ -503,7 +504,11 @@ class OC_DB { } // Create new tables - self::createDBFromStructure( $file ); + if( self::createDBFromStructure( $file ) ){ + return true; + } else { + return false; + } } diff --git a/lib/migrate.php b/lib/migrate.php index 338d091af8b..0058de73919 100644 --- a/lib/migrate.php +++ b/lib/migrate.php @@ -122,7 +122,6 @@ class OC_Migrate{ } } // Create the zip object - self::$zip = new ZipArchive; if( !self::createZip() ){ return false; } @@ -188,6 +187,177 @@ class OC_Migrate{ return self::$zippath; } + /** + * @breif imports a user, or owncloud instance + * @param $path string path to zip + * @param optional $uid userid of new user + */ + public static function import( $path, $uid=null ){ + OC_Util::checkAdminUser(); + $datadir = OC_Config::getValue( 'datadirectory' ); + // Extract the zip + if( !$extractpath = self::extractZip( $path ) ){ + return false; + } + // Get export_info.json + $scan = scandir( $extractpath ); + // Check for export_info.json + if( !in_array( 'export_info.json', $scan ) ){ + OC_Log::write( 'migration', 'Invalid import file, export_info.json note found', OC_Log::ERROR ); + return false; + } + $json = json_decode( file_get_contents( $extractpath . 'export_info.json' ) ); + self::$exporttype = $json->exporttype; + + // Have we got a user if type is user + if( self::$exporttype == 'user' ){ + if( !$uid ){ + self::$uid = $json->exporteduser; + } else { + self::$uid = $uid; + } + } + + // Handle export types + switch( self::$exporttype ){ + case 'user': + // Check user availability + if( OC_User::userExists( self::$uid ) ){ + OC_Log::write( 'migration', 'User already exists', OC_Log::ERROR ); + return false; + } + // Create the user + if( !self::createUser( self::$uid, $json->hash ) ){ + return false; + } + // Make the new users data dir + $path = $datadir . '/' . self::$uid . '/files/'; + if( !mkdir( $path, 0755, true ) ){ + OC_Log::write( 'migration', 'Failed to create users data dir: '.$path, OC_Log::ERROR ); + return false; + } + // Copy data + if( !self::copy_r( $extractpath . $json->exporteduser . '/files', $datadir . '/' . self::$uid . '/files' ) ){ + return false; + } + // Import user app data + if( !self::importAppData( $extractpath . $json->exporteduser . '/migration.db', $json, self::$uid ) ){ + return false; + } + // All done! + if( !self::unlink_r( $extractpath ) ){ + OC_Log::write( 'migration', 'Failed to delete the extracted zip', OC_Log::ERROR ); + } + return true; + break; + case 'instance': + // Check for new data dir and dbexport before doing anything + // TODO + /* + // Delete current data folder. + OC_Log::write( 'migration', "Deleting current data dir", OC_Log::INFO ); + if( self::unlink_r( $datadir, false ) ){ + OC_Log::write( 'migration', 'Failed to delete the current data dir', OC_Log::ERROR ); + return false; + } + + // Copy over data + if( !self::copy_r( $extractname . 'data', $datadir ) ){ + OC_Log::write( 'migration', 'Failed to copy over data directory', OC_Log::ERROR ); + return false; + } + */ + // Import the db + if( !OC_DB::replaceDB( $extractpath . 'dbexport.xml' ) ){ + return false; + } + // Done + return true; + break; + } + + } + + /** + * @breif recursively deletes a directory + * @param $dir string path of dir to delete + * $param optional $deleteRootToo bool delete the root directory + * @return bool + */ + private static function unlink_r( $dir, $deleteRootToo=true ){ + if( !$dh = @opendir( $dir ) ){ + return false; + } + while (false !== ($obj = readdir($dh))){ + if($obj == '.' || $obj == '..') { + continue; + } + if (!@unlink($dir . '/' . $obj)){ + self::unlink_r($dir.'/'.$obj, true); + } + } + closedir($dh); + if ( $deleteRootToo ) { + @rmdir($dir); + } + return true; + } + + /** + * @breif copies recursively + * @param $path string path to source folder + * @param $dest string path to destination + * @return bool + */ + private static function copy_r( $path, $dest ){ + if( is_dir($path) ){ + @mkdir( $dest ); + $objects = scandir( $path ); + if( sizeof( $objects ) > 0 ){ + foreach( $objects as $file ){ + if( $file == "." || $file == ".." ) + continue; + // go on + if( is_dir( $path . '/' . $file ) ){ + self::copy_r( $path .'/' . $file, $dest . '/' . $file ); + } else { + copy( $path . '/' . $file, $dest . '/' . $file ); + } + } + } + return true; + } + elseif( is_file( $path ) ){ + return copy( $path, $dest ); + } else { + return false; + } + } + + /** + * @breif tries to extract the import zip + * @param $path string path to the zip + * @return string path to extract location (with a trailing slash) or false on failure + */ + static private function extractZip( $path ){ + self::$zip = new ZipArchive; + // Validate path + if( !file_exists( $path ) ){ + OC_Log::write( 'migration', 'Zip not found', OC_Log::ERROR ); + return false; + } + if ( self::$zip->open( $path ) != TRUE ) { + OC_Log::write( 'migration', "Failed to open zip file", OC_Log::ERROR ); + return false; + } + $to = get_temp_dir() . '/oc_import_' . self::$exporttype . '_' . date("y-m-d_H-i-s") . '/'; + if( !self::$zip->extractTo( $to ) ){ + return false; + } + self::$zip->close(); + return $to; + } + /** * @brief connects to a MDB2 database scheme * @returns bool @@ -272,7 +442,6 @@ class OC_Migrate{ $result = $query->execute( array( self::$uid ) ); $row = $result->fetchRow(); $hash = $row ? $row['password'] : false; - die(var_dump($hash)); if( !$hash ){ OC_Log::write( 'migration', 'Failed to get the users password hash', OC_log::ERROR); return false; @@ -287,7 +456,7 @@ class OC_Migrate{ $info = array_merge( $info, (array)$array ); // Create json $json = json_encode( $info ); - return true; + return $json; } /** @@ -399,8 +568,9 @@ class OC_Migrate{ * @return bool */ static private function createZip(){ + self::$zip = new ZipArchive; // Check if properties are set - if( !self::$zip || !self::$zippath ){ + if( !self::$zippath ){ OC_Log::write('migration', 'createZip() called but $zip and/or $zippath have not been set', OC_Log::ERROR); return false; } @@ -435,9 +605,6 @@ class OC_Migrate{ * @return bool if the import succedded */ public static function importAppData( $db, $info, $uid=null ){ - - self::$uid = !is_null( $uid ) ? $uid : $info->exporteduser; - // Check if the db exists if( file_exists( $db ) ){ // Connect to the db @@ -466,12 +633,11 @@ class OC_Migrate{ // Did it succeed? if( $info->apps->$id->success ){ // Give the provider the content object - // TODO PASS THE PATH TO MIGRATION.DB - if( !self::connectDB() ){ + if( !self::connectDB( $db ) ){ return false; } - $content = new OC_Migration_Content( self::$zip, self::$db ); - $provider->setObject( $content ); + $content = new OC_Migration_Content( self::$zip, self::$MDB2 ); + $provider->setData( self::$uid, $content, $info ); // Then do the import $provider->import( $info->apps->$id, $importinfo ); } diff --git a/lib/migration/content.php b/lib/migration/content.php index fe8a21a45b4..d25b5af293c 100644 --- a/lib/migration/content.php +++ b/lib/migration/content.php @@ -53,7 +53,7 @@ class OC_Migration_Content{ $query = $this->processQuery( $query ); // Optimize the query - $query = $this->MDB2->prepare( $query ); + $query = $this->db->prepare( $query ); // Die if we have an error (error means: bad query, not 0 results!) if( PEAR::isError( $query ) ) { @@ -174,7 +174,9 @@ class OC_Migration_Content{ $dirname = basename($dir); $this->zip->addEmptyDir($internaldir . $dirname); $internaldir.=$dirname.='/'; - + if( !file_exists( $dir ) ){ + return false; + } if ($dirhandle = opendir($dir)) { while (false !== ( $file = readdir($dirhandle))) { diff --git a/lib/migration/provider.php b/lib/migration/provider.php index b9e2c476203..d592ed67264 100644 --- a/lib/migration/provider.php +++ b/lib/migration/provider.php @@ -7,7 +7,7 @@ abstract class OC_Migration_Provider{ protected $id=false; protected $content=false; protected $uid=false; - protected $info=false; + protected $olduid=false; protected $appinfo=false; public function __construct( $appid ){ @@ -32,11 +32,13 @@ abstract class OC_Migration_Provider{ * @breif sets the OC_Migration_Content object to $this->content * @param $content a OC_Migration_Content object */ - public function setData( $uid, $content, $info=false, $appinfo=false ){ + public function setData( $uid, $content, $info=false ){ $this->content = $content; $this->uid = $uid; - $this->info = $info; - $this->appinfo = $appinfo; + $this->olduid = $info->exporteduser; + $id = $this->id; + $this->appinfo = $info->apps->$id; + } /**