aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Needham <needham.thomas@gmail.com>2012-03-20 20:19:21 +0000
committerTom Needham <needham.thomas@gmail.com>2012-03-20 20:19:21 +0000
commit514c9ad8e7df1d7882adc33c42eb32a209537273 (patch)
treef39dae7822c3b7ddf678861a41a0ceea93e267f2
parent145d6f35660669397eaee08988ffbad1b65daff0 (diff)
downloadnextcloud-server-514c9ad8e7df1d7882adc33c42eb32a209537273.tar.gz
nextcloud-server-514c9ad8e7df1d7882adc33c42eb32a209537273.zip
Added unified import method.
-rw-r--r--apps/admin_export/settings.php10
-rw-r--r--apps/bookmarks/lib/migrate.php10
-rw-r--r--apps/user_migrate/admin.php18
-rw-r--r--lib/db.php7
-rw-r--r--lib/migrate.php188
-rw-r--r--lib/migration/content.php6
-rw-r--r--lib/migration/provider.php10
7 files changed, 206 insertions, 43 deletions
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;
}
@@ -189,6 +188,177 @@ class OC_Migrate{
}
/**
+ * @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;
+
}
/**