Merge pull request #12380 from owncloud/remove-oc-migrate

Remove OC_Migrate
This commit is contained in:
Lukas Reschke 2014-11-25 00:25:37 +01:00
commit eb1dcb87c1
4 changed files with 0 additions and 1022 deletions

View file

@ -1,626 +0,0 @@
<?php
/**
* ownCloud
*
* @author Tom Needham
* @copyright 2012 Tom Needham tom@owncloud.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* provides an interface to migrate users and whole ownclouds
*/
class OC_Migrate{
// Array of OC_Migration_Provider objects
static private $providers=array();
// User id of the user to import/export
static private $uid=false;
// Holds the ZipArchive object
static private $zip=false;
// Stores the type of export
static private $exporttype=false;
// Holds the db object
static private $migration_database=false;
// Path to the sqlite db
static private $dbpath=false;
// Holds the path to the zip file
static private $zippath=false;
// Holds the OC_Migration_Content object
static private $content=false;
/**
* register a new migration provider
* @param OC_Migration_Provider $provider
*/
public static function registerProvider($provider) {
self::$providers[]=$provider;
}
/**
* finds and loads the providers
*/
static private function findProviders() {
// Find the providers
$apps = OC_App::getAllApps();
foreach($apps as $app) {
$path = OC_App::getAppPath($app) . '/appinfo/migrate.php';
if( file_exists( $path ) ) {
include_once $path;
}
}
}
/**
* exports a user, or owncloud instance
* @param string $uid user id of user to export if export type is user, defaults to current
* @param string $type type of export, defualts to user
* @param string $path path to zip output folder
* @return string on error, path to zip on success
*/
public static function export( $uid=null, $type='user', $path=null ) {
$datadir = OC_Config::getValue( 'datadirectory' );
// Validate export type
$types = array( 'user', 'instance', 'system', 'userfiles' );
if( !in_array( $type, $types ) ) {
OC_Log::write( 'migration', 'Invalid export type', OC_Log::ERROR );
return json_encode( array( 'success' => false ) );
}
self::$exporttype = $type;
// Userid?
if( self::$exporttype == 'user' ) {
// Check user exists
self::$uid = is_null($uid) ? OC_User::getUser() : $uid;
if(!OC_User::userExists(self::$uid)) {
return json_encode( array( 'success' => false) );
}
}
// Calculate zipname
if( self::$exporttype == 'user' ) {
$zipname = 'oc_export_' . self::$uid . '_' . date("y-m-d_H-i-s") . '.zip';
} else {
$zipname = 'oc_export_' . self::$exporttype . '_' . date("y-m-d_H-i-s") . '.zip';
}
// Calculate path
if( self::$exporttype == 'user' ) {
self::$zippath = $datadir . '/' . self::$uid . '/' . $zipname;
} else {
if( !is_null( $path ) ) {
// Validate custom path
if( !file_exists( $path ) || !is_writeable( $path ) ) {
OC_Log::write( 'migration', 'Path supplied is invalid.', OC_Log::ERROR );
return json_encode( array( 'success' => false ) );
}
self::$zippath = $path . $zipname;
} else {
// Default path
self::$zippath = get_temp_dir() . '/' . $zipname;
}
}
// Create the zip object
if( !self::createZip() ) {
return json_encode( array( 'success' => false ) );
}
// Do the export
self::findProviders();
$exportdata = array();
switch( self::$exporttype ) {
case 'user':
// Connect to the db
self::$dbpath = $datadir . '/' . self::$uid . '/migration.db';
if( !self::connectDB() ) {
return json_encode( array( 'success' => false ) );
}
self::$content = new OC_Migration_Content( self::$zip, self::$migration_database );
// Export the app info
$exportdata = self::exportAppData();
// Add the data dir to the zip
self::$content->addDir(OC_User::getHome(self::$uid), true, '/' );
break;
case 'instance':
self::$content = new OC_Migration_Content( self::$zip );
// Creates a zip that is compatable with the import function
$dbfile = tempnam( get_temp_dir(), "owncloud_export_data_" );
OC_DB::getDbStructure( $dbfile, 'MDB2_SCHEMA_DUMP_ALL');
// Now add in *dbname* and *dbprefix*
$dbexport = file_get_contents( $dbfile );
$dbnamestring = "<database>\n\n <name>" . OC_Config::getValue( "dbname", "owncloud" );
$dbtableprefixstring = "<table>\n\n <name>" . OC_Config::getValue( "dbtableprefix", "oc_" );
$dbexport = str_replace( $dbnamestring, "<database>\n\n <name>*dbname*", $dbexport );
$dbexport = str_replace( $dbtableprefixstring, "<table>\n\n <name>*dbprefix*", $dbexport );
// Add the export to the zip
self::$content->addFromString( $dbexport, "dbexport.xml" );
// Add user data
foreach(OC_User::getUsers() as $user) {
self::$content->addDir(OC_User::getHome($user), true, "/userdata/" );
}
break;
case 'userfiles':
self::$content = new OC_Migration_Content( self::$zip );
// Creates a zip with all of the users files
foreach(OC_User::getUsers() as $user) {
self::$content->addDir(OC_User::getHome($user), true, "/" );
}
break;
case 'system':
self::$content = new OC_Migration_Content( self::$zip );
// Creates a zip with the owncloud system files
self::$content->addDir( OC::$SERVERROOT . '/', false, '/');
foreach (array(
".git",
"3rdparty",
"apps",
"core",
"files",
"l10n",
"lib",
"ocs",
"search",
"settings",
"tests"
) as $dir) {
self::$content->addDir( OC::$SERVERROOT . '/' . $dir, true, "/");
}
break;
}
if( !$info = self::getExportInfo( $exportdata ) ) {
return json_encode( array( 'success' => false ) );
}
// Add the export info json to the export zip
self::$content->addFromString( $info, 'export_info.json' );
if( !self::$content->finish() ) {
return json_encode( array( 'success' => false ) );
}
return json_encode( array( 'success' => true, 'data' => self::$zippath ) );
}
/**
* imports a user, or owncloud instance
* @param string $path path to zip
* @param string $type type of import (user or instance)
* @param string|null|int $uid userid of new user
* @return string
*/
public static function import( $path, $type='user', $uid=null ) {
$datadir = OC_Config::getValue( 'datadirectory' );
// Extract the zip
if( !$extractpath = self::extractZip( $path ) ) {
return json_encode( array( 'success' => 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 not found', OC_Log::ERROR );
return json_encode( array( 'success' => false ) );
}
$json = json_decode( file_get_contents( $extractpath . 'export_info.json' ) );
if( $json->exporttype != $type ) {
OC_Log::write( 'migration', 'Invalid import file', OC_Log::ERROR );
return json_encode( array( 'success' => false ) );
}
self::$exporttype = $type;
$currentuser = OC_User::getUser();
// Have we got a user if type is user
if( self::$exporttype == 'user' ) {
self::$uid = !is_null($uid) ? $uid : $currentuser;
}
// We need to be an admin if we are not importing our own data
if(($type == 'user' && self::$uid != $currentuser) || $type != 'user' ) {
if( !OC_User::isAdminUser($currentuser)) {
// Naughty.
OC_Log::write( 'migration', 'Import not permitted.', OC_Log::ERROR );
return json_encode( array( 'success' => false ) );
}
}
// Handle export types
switch( self::$exporttype ) {
case 'user':
// Check user availability
if( !OC_User::userExists( self::$uid ) ) {
OC_Log::write( 'migration', 'User doesn\'t exist', OC_Log::ERROR );
return json_encode( array( 'success' => false ) );
}
// Check if the username is valid
if( preg_match( '/[^a-zA-Z0-9 _\.@\-]/', $json->exporteduser )) {
OC_Log::write( 'migration', 'Username is not valid', OC_Log::ERROR );
return json_encode( array( 'success' => false ) );
}
// Copy data
$userfolder = $extractpath . $json->exporteduser;
$newuserfolder = $datadir . '/' . self::$uid;
foreach(scandir($userfolder) as $file){
if($file !== '.' && $file !== '..' && is_dir($userfolder.'/'.$file)) {
$file = str_replace(array('/', '\\'), '', $file);
// Then copy the folder over
OC_Helper::copyr($userfolder.'/'.$file, $newuserfolder.'/'.$file);
}
}
// Import user app data
if(file_exists($extractpath . $json->exporteduser . '/migration.db')) {
if( !$appsimported = self::importAppData( $extractpath . $json->exporteduser . '/migration.db',
$json,
self::$uid ) ) {
return json_encode( array( 'success' => false ) );
}
}
// All done!
if( !self::unlink_r( $extractpath ) ) {
OC_Log::write( 'migration', 'Failed to delete the extracted zip', OC_Log::ERROR );
}
return json_encode( array( 'success' => true, 'data' => $appsimported ) );
break;
case 'instance':
/*
* EXPERIMENTAL
// 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 json_encode( array( 'success' => false ) );
}
// Copy over data
if( !self::copy_r( $extractpath . 'userdata', $datadir ) ) {
OC_Log::write( 'migration', 'Failed to copy over data directory', OC_Log::ERROR );
return json_encode( array( 'success' => false ) );
}
// Import the db
if( !OC_DB::replaceDB( $extractpath . 'dbexport.xml' ) ) {
return json_encode( array( 'success' => false ) );
}
// Done
return json_encode( array( 'success' => true ) );
*/
break;
}
}
/**
* recursively deletes a directory
* @param string $dir path of dir to delete
* @param bool $deleteRootToo 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;
}
/**
* tries to extract the import zip
* @param string $path 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;
}
/**
* creates a migration.db in the users data dir with their app data in
* @return bool whether operation was successfull
*/
private static function exportAppData( ) {
$success = true;
$return = array();
// Foreach provider
foreach( self::$providers as $provider ) {
// Check if the app is enabled
if( OC_App::isEnabled( $provider->getID() ) ) {
$success = true;
// Does this app use the database?
if( file_exists( OC_App::getAppPath($provider->getID()).'/appinfo/database.xml' ) ) {
// Create some app tables
$tables = self::createAppTables( $provider->getID() );
if( is_array( $tables ) ) {
// Save the table names
foreach($tables as $table) {
$return['apps'][$provider->getID()]['tables'][] = $table;
}
} else {
// It failed to create the tables
$success = false;
}
}
// Run the export function?
if( $success ) {
// Set the provider properties
$provider->setData( self::$uid, self::$content );
$return['apps'][$provider->getID()]['success'] = $provider->export();
} else {
$return['apps'][$provider->getID()]['success'] = false;
$return['apps'][$provider->getID()]['message'] = 'failed to create the app tables';
}
// Now add some app info the the return array
$appinfo = OC_App::getAppInfo( $provider->getID() );
$return['apps'][$provider->getID()]['version'] = OC_App::getAppVersion($provider->getID());
}
}
return $return;
}
/**
* generates json containing export info, and merges any data supplied
* @param array $array of data to include in the returned json
* @return string
*/
static private function getExportInfo( $array=array() ) {
$info = array(
'ocversion' => OC_Util::getVersion(),
'exporttime' => time(),
'exportedby' => OC_User::getUser(),
'exporttype' => self::$exporttype,
'exporteduser' => self::$uid
);
if( !is_array( $array ) ) {
OC_Log::write( 'migration', 'Supplied $array was not an array in getExportInfo()', OC_Log::ERROR );
}
// Merge in other data
$info = array_merge( $info, (array)$array );
// Create json
$json = json_encode( $info );
return $json;
}
/**
* connects to migration.db, or creates if not found
* @param string $path to migration.db, defaults to user data dir
* @return bool whether the operation was successful
*/
static private function connectDB( $path=null ) {
// Has the dbpath been set?
self::$dbpath = !is_null( $path ) ? $path : self::$dbpath;
if( !self::$dbpath ) {
OC_Log::write( 'migration', 'connectDB() was called without dbpath being set', OC_Log::ERROR );
return false;
}
// Already connected
if(!self::$migration_database) {
$datadir = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" );
$connectionParams = array(
'path' => self::$dbpath,
'driver' => 'pdo_sqlite',
);
$connectionParams['adapter'] = '\OC\DB\AdapterSqlite';
$connectionParams['wrapperClass'] = 'OC\DB\Connection';
$connectionParams['tablePrefix'] = '';
// Try to establish connection
self::$migration_database = \Doctrine\DBAL\DriverManager::getConnection($connectionParams);
}
return true;
}
/**
* creates the tables in migration.db from an apps database.xml
* @param string $appid id of the app
* @return bool whether the operation was successful
*/
static private function createAppTables( $appid ) {
$schema_manager = new OC\DB\MDB2SchemaManager(self::$migration_database);
// There is a database.xml file
$content = file_get_contents(OC_App::getAppPath($appid) . '/appinfo/database.xml' );
$file2 = 'static://db_scheme';
// TODO get the relative path to migration.db from the data dir
// For now just cheat
$path = pathinfo( self::$dbpath );
$content = str_replace( '*dbname*', self::$uid.'/migration', $content );
$content = str_replace( '*dbprefix*', '', $content );
$xml = new SimpleXMLElement($content);
foreach($xml->table as $table) {
$tables[] = (string)$table->name;
}
file_put_contents( $file2, $content );
// Try to create tables
try {
$schema_manager->createDbFromStructure($file2);
} catch(Exception $e) {
unlink( $file2 );
OC_Log::write( 'migration', 'Failed to create tables for: '.$appid, OC_Log::FATAL );
OC_Log::write( 'migration', $e->getMessage(), OC_Log::FATAL );
return false;
}
return $tables;
}
/**
* tries to create the zip
* @return bool
*/
static private function createZip() {
self::$zip = new ZipArchive;
// Check if properties are set
if( !self::$zippath ) {
OC_Log::write('migration', 'createZip() called but $zip and/or $zippath have not been set', OC_Log::ERROR);
return false;
}
if ( self::$zip->open( self::$zippath, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE ) !== true ) {
OC_Log::write('migration',
'Failed to create the zip with error: '.self::$zip->getStatusString(),
OC_Log::ERROR);
return false;
} else {
return true;
}
}
/**
* returns an array of apps that support migration
* @return array
*/
static public function getApps() {
$allapps = OC_App::getAllApps();
foreach($allapps as $app) {
$path = self::getAppPath($app) . '/lib/migrate.php';
if( file_exists( $path ) ) {
$supportsmigration[] = $app;
}
}
return $supportsmigration;
}
/**
* imports a new user
* @param string $db string path to migration.db
* @param object $info object of migration info
* @param string|null|int $uid uid to use
* @return array an array of apps with import statuses, or false on failure.
*/
public static function importAppData( $db, $info, $uid=null ) {
// Check if the db exists
if( file_exists( $db ) ) {
// Connect to the db
if(!self::connectDB( $db )) {
OC_Log::write('migration', 'Failed to connect to migration.db', OC_Log::ERROR);
return false;
}
} else {
OC_Log::write('migration', 'Migration.db not found at: '.$db, OC_Log::FATAL );
return false;
}
// Find providers
self::findProviders();
// Generate importinfo array
$importinfo = array(
'olduid' => $info->exporteduser,
'newuid' => self::$uid
);
foreach( self::$providers as $provider) {
// Is the app in the export?
$id = $provider->getID();
if( isset( $info->apps->$id ) ) {
// Is the app installed
if( !OC_App::isEnabled( $id ) ) {
OC_Log::write( 'migration',
'App: ' . $id . ' is not installed, can\'t import data.',
OC_Log::INFO );
$appsstatus[$id] = 'notsupported';
} else {
// Did it succeed on export?
if( $info->apps->$id->success ) {
// Give the provider the content object
if( !self::connectDB( $db ) ) {
return false;
}
$content = new OC_Migration_Content( self::$zip, self::$migration_database );
$provider->setData( self::$uid, $content, $info );
// Then do the import
if( !$appsstatus[$id] = $provider->import( $info->apps->$id, $importinfo ) ) {
// Failed to import app
OC_Log::write( 'migration',
'Failed to import app data for user: ' . self::$uid . ' for app: ' . $id,
OC_Log::ERROR );
}
} else {
// Add to failed list
$appsstatus[$id] = false;
}
}
}
}
return $appsstatus;
}
/**
* creates a new user in the database
* @param string $uid user_id of the user to be created
* @param string $hash hash of the user to be created
* @return bool result of user creation
*/
public static function createUser( $uid, $hash ) {
// Check if userid exists
if(OC_User::userExists( $uid )) {
return false;
}
// Create the user
$query = OC_DB::prepare( "INSERT INTO `*PREFIX*users` ( `uid`, `password` ) VALUES( ?, ? )" );
$result = $query->execute( array( $uid, $hash));
if( !$result ) {
OC_Log::write('migration', 'Failed to create the new user "'.$uid."", OC_Log::ERROR);
}
return $result ? true : false;
}
}

View file

@ -1,246 +0,0 @@
<?php
/**
* ownCloud
*
* @author Tom Needham
* @copyright 2012 Tom Needham tom@owncloud.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* provides methods to add and access data from the migration
*/
class OC_Migration_Content{
private $zip=false;
// Holds the database object
private $db=null;
// Holds an array of tmpfiles to delete after zip creation
private $tmpfiles=array();
/**
* sets up the
* @param ZipArchive $zip ZipArchive object
* @param object $db a database object (required for exporttype user)
* @return bool|null
*/
public function __construct( $zip, $db=null ) {
$this->zip = $zip;
$this->db = $db;
}
/**
* prepares the db
* @param string $query the sql query to prepare
*/
public function prepare( $query ) {
// Only add database to tmpfiles if actually used
if( !is_null( $this->db ) ) {
// Get db path
$db = $this->db->getDatabase();
if(!in_array($db, $this->tmpfiles)) {
$this->tmpfiles[] = $db;
}
}
// Optimize the query
$query = $this->processQuery( $query );
// Optimize the query
$query = $this->db->prepare( $query );
$query = new OC_DB_StatementWrapper($query, false);
return $query;
}
/**
* processes the db query
* @param string $query the query to process
* @return string of processed query
*/
private function processQuery( $query ) {
$query = str_replace( '`', '\'', $query );
$query = str_replace( 'NOW()', 'datetime(\'now\')', $query );
$query = str_replace( 'now()', 'datetime(\'now\')', $query );
// remove table prefixes
$query = str_replace( '*PREFIX*', '', $query );
return $query;
}
/**
* copys rows to migration.db from the main database
* @param array $options array of options.
* @return bool
*/
public function copyRows( $options ) {
if( !array_key_exists( 'table', $options ) ) {
return false;
}
$return = array();
// Need to include 'where' in the query?
if( array_key_exists( 'matchval', $options ) && array_key_exists( 'matchcol', $options ) ) {
// If only one matchval, create an array
if(!is_array($options['matchval'])) {
$options['matchval'] = array( $options['matchval'] );
}
foreach( $options['matchval'] as $matchval ) {
// Run the query for this match value (where x = y value)
$sql = 'SELECT * FROM `*PREFIX*' . $options['table'] . '` WHERE `' . $options['matchcol'] . '` = ?';
$query = OC_DB::prepare( $sql );
$results = $query->execute( array( $matchval ) );
$newreturns = $this->insertData( $results, $options );
$return = array_merge( $return, $newreturns );
}
} else {
// Just get everything
$sql = 'SELECT * FROM `*PREFIX*' . $options['table'] . '`';
$query = OC_DB::prepare( $sql );
$results = $query->execute();
$return = $this->insertData( $results, $options );
}
return $return;
}
/**
* saves a sql data set into migration.db
* @param OC_DB_StatementWrapper $data a sql data set returned from self::prepare()->query()
* @param array $options array of copyRows options
* @return void
*/
private function insertData( $data, $options ) {
$return = array();
// Foreach row of data to insert
while( $row = $data->fetchRow() ) {
// Now save all this to the migration.db
foreach($row as $field=>$value) {
$fields[] = $field;
$values[] = $value;
}
// Generate some sql
$sql = "INSERT INTO `" . $options['table'] . '` ( `';
$fieldssql = implode( '`, `', $fields );
$sql .= $fieldssql . "` ) VALUES( ";
$valuessql = substr( str_repeat( '?, ', count( $fields ) ), 0, -2 );
$sql .= $valuessql . " )";
// Make the query
$query = $this->prepare( $sql );
$query->execute( $values );
// Do we need to return some values?
if( array_key_exists( 'idcol', $options ) ) {
// Yes we do
$return[] = $row[$options['idcol']];
} else {
// Take a guess and return the first field :)
$return[] = reset($row);
}
$fields = '';
$values = '';
}
return $return;
}
/**
* adds a directory to the zip object
* @param boolean|string $dir string path of the directory to add
* @param bool $recursive
* @param string $internaldir path of folder to add dir to in zip
* @return bool
*/
public function addDir( $dir, $recursive=true, $internaldir='' ) {
$dirname = basename($dir);
$this->zip->addEmptyDir($internaldir . $dirname);
$internaldir.=$dirname.='/';
if( !file_exists( $dir ) ) {
return false;
}
$dirhandle = opendir($dir);
if(is_resource($dirhandle)) {
while (false !== ( $file = readdir($dirhandle))) {
if (( $file != '.' ) && ( $file != '..' )) {
if (is_dir($dir . '/' . $file) && $recursive) {
$this->addDir($dir . '/' . $file, $recursive, $internaldir);
} elseif (is_file($dir . '/' . $file)) {
$this->zip->addFile($dir . '/' . $file, $internaldir . $file);
}
}
}
closedir($dirhandle);
} else {
OC_Log::write('admin_export', "Was not able to open directory: " . $dir, OC_Log::ERROR);
return false;
}
return true;
}
/**
* adds a file to the zip from a given string
* @param string $data string of data to add
* @param string $path the relative path inside of the zip to save the file to
* @return bool
*/
public function addFromString( $data, $path ) {
// Create a temp file
$file = tempnam( get_temp_dir(). '/', 'oc_export_tmp_' );
$this->tmpfiles[] = $file;
if( !file_put_contents( $file, $data ) ) {
OC_Log::write( 'migation', 'Failed to save data to a temporary file', OC_Log::ERROR );
return false;
}
// Add file to the zip
$this->zip->addFile( $file, $path );
return true;
}
/**
* closes the zip, removes temp files
* @return bool
*/
public function finish() {
if( !$this->zip->close() ) {
OC_Log::write( 'migration',
'Failed to write the zip file with error: '.$this->zip->getStatusString(),
OC_Log::ERROR );
return false;
}
$this->cleanup();
return true;
}
/**
* cleans up after the zip
*/
private function cleanup() {
// Delete tmp files
foreach($this->tmpfiles as $i) {
unlink( $i );
}
}
}

View file

@ -1,52 +0,0 @@
<?php
/**
* provides search functionalty
*/
abstract class OC_Migration_Provider{
protected $id=false;
protected $content=false;
protected $uid=false;
protected $olduid=false;
protected $appinfo=false;
public function __construct( $appid ) {
// Set the id
$this->id = $appid;
OC_Migrate::registerProvider( $this );
}
/**
* exports data for apps
* @return array appdata to be exported
*/
abstract function export( );
/**
* imports data for the app
* @return void
*/
abstract function import( );
/**
* sets the OC_Migration_Content object to $this->content
* @param OC_Migration_Content $content a OC_Migration_Content object
*/
public function setData( $uid, $content, $info=null ) {
$this->content = $content;
$this->uid = $uid;
$id = $this->id;
if( !is_null( $info ) ) {
$this->olduid = $info->exporteduser;
$this->appinfo = $info->apps->$id;
}
}
/**
* returns the appid of the provider
* @return string
*/
public function getID() {
return $this->id;
}
}

View file

@ -1,98 +0,0 @@
<?php
/**
* Copyright (c) 2014 Tom Needham <tom@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
class Test_Migrate extends \Test\TestCase {
public $users;
public $tmpfiles = array();
/** @var \OC\Files\Storage\Storage */
private $originalStorage;
protected function setUp() {
parent::setUp();
$this->originalStorage = \OC\Files\Filesystem::getStorage('/');
}
protected function tearDown() {
$u = new OC_User();
foreach($this->users as $user) {
$u->deleteUser($user);
}
foreach($this->tmpfiles as $file) {
\OC_Helper::rmdirr($file);
}
\OC\Files\Filesystem::mount($this->originalStorage, array(), '/');
parent::tearDown();
}
/**
* Generates a test user and sets up their file system
* @return string the test users id
*/
public function generateUser() {
$username = $this->getUniqueID();
\OC_User::createUser($username, 'password');
\OC_Util::tearDownFS();
\OC_User::setUserId('');
\OC\Files\Filesystem::tearDown();
\OC_Util::setupFS($username);
$this->users[] = $username;
return $username;
}
/**
* validates an export for a user
* checks for existence of export_info.json and file folder
* @param string $exportedUser the user that was exported
* @param string $path the path to the .zip export
* @param string $exportedBy
*/
public function validateUserExport($exportedBy, $exportedUser, $path) {
$this->assertTrue(file_exists($path));
// Extract
$extract = get_temp_dir() . '/oc_import_' . uniqid();
//mkdir($extract);
$this->tmpfiles[] = $extract;
$zip = new ZipArchive;
$zip->open($path);
$zip->extractTo($extract);
$zip->close();
$this->assertTrue(file_exists($extract.'/export_info.json'));
$exportInfo = file_get_contents($extract.'/export_info.json');
$exportInfo = json_decode($exportInfo);
$this->assertNotNull($exportInfo);
$this->assertEquals($exportedUser, $exportInfo->exporteduser);
$this->assertEquals($exportedBy, $exportInfo->exportedby);
$this->assertTrue(file_exists($extract.'/'.$exportedUser.'/files'));
}
public function testUserSelfExport() {
// Create a user
$user = $this->generateUser();
\OC_User::setUserId($user);
$export = \OC_Migrate::export($user);
// Check it succeeded and exists
$this->assertTrue(json_decode($export)->success);
// Validate the export
$this->validateUserExport($user, $user, json_decode($export)->data);
}
public function testUserOtherExport() {
$user = $this->generateUser();
$user2 = $this->generateUser();
\OC_User::setUserId($user2);
$export = \OC_Migrate::export($user);
// Check it succeeded and exists
$this->assertTrue(json_decode($export)->success);
// Validate the export
$this->validateUserExport($user2, $user, json_decode($export)->data);
}
}