2012-03-19 20:44:20 +00:00
|
|
|
<?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{
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
private $zip=false;
|
2013-11-22 14:53:56 +00:00
|
|
|
// Holds the database object
|
2012-03-31 23:20:08 +00:00
|
|
|
private $db=null;
|
2012-03-19 20:44:20 +00:00
|
|
|
// Holds an array of tmpfiles to delete after zip creation
|
2012-09-18 16:25:34 +00:00
|
|
|
private $tmpfiles=array();
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
/**
|
2014-05-19 15:50:53 +00:00
|
|
|
* sets up the
|
2014-02-19 08:31:54 +00:00
|
|
|
* @param ZipArchive $zip ZipArchive object
|
2014-05-11 20:51:30 +00:00
|
|
|
* @param object $db a database object (required for exporttype user)
|
2014-04-21 13:44:54 +00:00
|
|
|
* @return bool|null
|
2012-03-19 20:44:20 +00:00
|
|
|
*/
|
2012-09-07 13:22:01 +00:00
|
|
|
public function __construct( $zip, $db=null ) {
|
2012-03-19 20:44:20 +00:00
|
|
|
|
|
|
|
$this->zip = $zip;
|
|
|
|
$this->db = $db;
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
}
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2014-02-06 15:30:58 +00:00
|
|
|
/**
|
2014-05-19 15:50:53 +00:00
|
|
|
* prepares the db
|
2014-05-11 20:51:30 +00:00
|
|
|
* @param string $query the sql query to prepare
|
2014-02-06 15:30:58 +00:00
|
|
|
*/
|
2012-09-07 13:22:01 +00:00
|
|
|
public function prepare( $query ) {
|
2012-10-14 19:04:08 +00:00
|
|
|
|
2012-09-18 16:25:34 +00:00
|
|
|
// Only add database to tmpfiles if actually used
|
|
|
|
if( !is_null( $this->db ) ) {
|
|
|
|
// Get db path
|
|
|
|
$db = $this->db->getDatabase();
|
2012-11-04 09:46:32 +00:00
|
|
|
if(!in_array($db, $this->tmpfiles)) {
|
2012-09-18 16:25:34 +00:00
|
|
|
$this->tmpfiles[] = $db;
|
|
|
|
}
|
|
|
|
}
|
2012-10-14 19:04:08 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
// Optimize the query
|
|
|
|
$query = $this->processQuery( $query );
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
// Optimize the query
|
2012-03-20 20:19:21 +00:00
|
|
|
$query = $this->db->prepare( $query );
|
2013-12-20 11:09:19 +00:00
|
|
|
$query = new OC_DB_StatementWrapper($query, false);
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2013-11-22 14:53:56 +00:00
|
|
|
return $query;
|
2012-03-19 20:44:20 +00:00
|
|
|
}
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
/**
|
2014-05-19 15:50:53 +00:00
|
|
|
* processes the db query
|
2014-02-19 08:31:54 +00:00
|
|
|
* @param string $query the query to process
|
2012-03-19 20:44:20 +00:00
|
|
|
* @return string of processed query
|
|
|
|
*/
|
2012-09-07 13:22:01 +00:00
|
|
|
private function processQuery( $query ) {
|
2012-03-19 20:44:20 +00:00
|
|
|
$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;
|
|
|
|
}
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
/**
|
2014-05-19 15:50:53 +00:00
|
|
|
* copys rows to migration.db from the main database
|
2014-05-11 20:51:30 +00:00
|
|
|
* @param array $options array of options.
|
2012-03-19 20:44:20 +00:00
|
|
|
* @return bool
|
|
|
|
*/
|
2012-09-07 13:22:01 +00:00
|
|
|
public function copyRows( $options ) {
|
|
|
|
if( !array_key_exists( 'table', $options ) ) {
|
2012-08-29 06:38:33 +00:00
|
|
|
return false;
|
2012-03-19 20:44:20 +00:00
|
|
|
}
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
$return = array();
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
// Need to include 'where' in the query?
|
2012-09-07 13:22:01 +00:00
|
|
|
if( array_key_exists( 'matchval', $options ) && array_key_exists( 'matchcol', $options ) ) {
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
// If only one matchval, create an array
|
2012-09-07 13:22:01 +00:00
|
|
|
if(!is_array($options['matchval'])) {
|
2012-08-29 06:38:33 +00:00
|
|
|
$options['matchval'] = array( $options['matchval'] );
|
2012-03-19 20:44:20 +00:00
|
|
|
}
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-09-07 13:22:01 +00:00
|
|
|
foreach( $options['matchval'] as $matchval ) {
|
2012-03-19 20:44:20 +00:00
|
|
|
// Run the query for this match value (where x = y value)
|
2013-07-29 16:36:52 +00:00
|
|
|
$sql = 'SELECT * FROM `*PREFIX*' . $options['table'] . '` WHERE `' . $options['matchcol'] . '` = ?';
|
2012-04-01 00:07:39 +00:00
|
|
|
$query = OC_DB::prepare( $sql );
|
2012-03-19 20:44:20 +00:00
|
|
|
$results = $query->execute( array( $matchval ) );
|
|
|
|
$newreturns = $this->insertData( $results, $options );
|
|
|
|
$return = array_merge( $return, $newreturns );
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// Just get everything
|
2012-07-30 18:46:14 +00:00
|
|
|
$sql = 'SELECT * FROM `*PREFIX*' . $options['table'] . '`';
|
2012-04-01 00:07:39 +00:00
|
|
|
$query = OC_DB::prepare( $sql );
|
2012-03-19 20:44:20 +00:00
|
|
|
$results = $query->execute();
|
|
|
|
$return = $this->insertData( $results, $options );
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
}
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
return $return;
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
}
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
/**
|
2014-05-19 15:50:53 +00:00
|
|
|
* saves a sql data set into migration.db
|
2014-02-19 08:31:54 +00:00
|
|
|
* @param OC_DB_StatementWrapper $data a sql data set returned from self::prepare()->query()
|
2014-05-11 20:51:30 +00:00
|
|
|
* @param array $options array of copyRows options
|
2012-03-19 20:44:20 +00:00
|
|
|
* @return void
|
|
|
|
*/
|
2012-09-07 13:22:01 +00:00
|
|
|
private function insertData( $data, $options ) {
|
2012-03-19 20:44:20 +00:00
|
|
|
$return = array();
|
2012-04-01 00:07:39 +00:00
|
|
|
// Foreach row of data to insert
|
2012-09-07 13:22:01 +00:00
|
|
|
while( $row = $data->fetchRow() ) {
|
2012-03-19 20:44:20 +00:00
|
|
|
// Now save all this to the migration.db
|
2012-09-07 13:22:01 +00:00
|
|
|
foreach($row as $field=>$value) {
|
2012-03-19 20:44:20 +00:00
|
|
|
$fields[] = $field;
|
|
|
|
$values[] = $value;
|
|
|
|
}
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
// Generate some sql
|
|
|
|
$sql = "INSERT INTO `" . $options['table'] . '` ( `';
|
|
|
|
$fieldssql = implode( '`, `', $fields );
|
|
|
|
$sql .= $fieldssql . "` ) VALUES( ";
|
2012-11-02 18:53:02 +00:00
|
|
|
$valuessql = substr( str_repeat( '?, ', count( $fields ) ), 0, -2 );
|
2012-03-19 20:44:20 +00:00
|
|
|
$sql .= $valuessql . " )";
|
|
|
|
// Make the query
|
|
|
|
$query = $this->prepare( $sql );
|
2013-11-22 14:53:56 +00:00
|
|
|
$query->execute( $values );
|
|
|
|
// Do we need to return some values?
|
|
|
|
if( array_key_exists( 'idcol', $options ) ) {
|
|
|
|
// Yes we do
|
|
|
|
$return[] = $row[$options['idcol']];
|
2012-03-19 20:44:20 +00:00
|
|
|
} else {
|
2013-11-22 14:53:56 +00:00
|
|
|
// Take a guess and return the first field :)
|
|
|
|
$return[] = reset($row);
|
2012-03-19 20:44:20 +00:00
|
|
|
}
|
2012-04-01 00:07:39 +00:00
|
|
|
$fields = '';
|
|
|
|
$values = '';
|
2012-03-19 20:44:20 +00:00
|
|
|
}
|
|
|
|
return $return;
|
|
|
|
}
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
/**
|
2014-05-19 15:50:53 +00:00
|
|
|
* adds a directory to the zip object
|
2014-02-06 15:30:58 +00:00
|
|
|
* @param boolean|string $dir string path of the directory to add
|
2014-05-11 20:51:30 +00:00
|
|
|
* @param bool $recursive
|
|
|
|
* @param string $internaldir path of folder to add dir to in zip
|
2012-03-19 20:44:20 +00:00
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function addDir( $dir, $recursive=true, $internaldir='' ) {
|
2013-02-09 21:44:11 +00:00
|
|
|
$dirname = basename($dir);
|
|
|
|
$this->zip->addEmptyDir($internaldir . $dirname);
|
|
|
|
$internaldir.=$dirname.='/';
|
2012-09-07 13:22:01 +00:00
|
|
|
if( !file_exists( $dir ) ) {
|
2012-08-29 06:38:33 +00:00
|
|
|
return false;
|
2012-03-20 20:19:21 +00:00
|
|
|
}
|
2013-09-05 09:58:57 +00:00
|
|
|
$dirhandle = opendir($dir);
|
|
|
|
if(is_resource($dirhandle)) {
|
2012-03-19 20:44:20 +00:00
|
|
|
while (false !== ( $file = readdir($dirhandle))) {
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
if (( $file != '.' ) && ( $file != '..' )) {
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
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);
|
2013-02-09 21:44:11 +00:00
|
|
|
} else {
|
2012-11-04 17:28:29 +00:00
|
|
|
OC_Log::write('admin_export', "Was not able to open directory: " . $dir, OC_Log::ERROR);
|
2012-03-19 20:44:20 +00:00
|
|
|
return false;
|
2013-02-09 21:44:11 +00:00
|
|
|
}
|
|
|
|
return true;
|
2012-03-19 20:44:20 +00:00
|
|
|
}
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
/**
|
2014-05-19 15:50:53 +00:00
|
|
|
* adds a file to the zip from a given string
|
2014-02-06 15:30:58 +00:00
|
|
|
* @param string $data string of data to add
|
|
|
|
* @param string $path the relative path inside of the zip to save the file to
|
2012-03-19 20:44:20 +00:00
|
|
|
* @return bool
|
|
|
|
*/
|
2012-09-07 13:22:01 +00:00
|
|
|
public function addFromString( $data, $path ) {
|
2012-03-19 20:44:20 +00:00
|
|
|
// Create a temp file
|
|
|
|
$file = tempnam( get_temp_dir(). '/', 'oc_export_tmp_' );
|
|
|
|
$this->tmpfiles[] = $file;
|
2012-09-07 13:22:01 +00:00
|
|
|
if( !file_put_contents( $file, $data ) ) {
|
2012-03-19 20:44:20 +00:00
|
|
|
OC_Log::write( 'migation', 'Failed to save data to a temporary file', OC_Log::ERROR );
|
2012-08-29 06:38:33 +00:00
|
|
|
return false;
|
2012-03-19 20:44:20 +00:00
|
|
|
}
|
|
|
|
// Add file to the zip
|
|
|
|
$this->zip->addFile( $file, $path );
|
|
|
|
return true;
|
|
|
|
}
|
2012-08-29 06:38:33 +00:00
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
/**
|
2014-05-19 15:50:53 +00:00
|
|
|
* closes the zip, removes temp files
|
2012-03-19 20:44:20 +00:00
|
|
|
* @return bool
|
|
|
|
*/
|
2012-09-07 13:22:01 +00:00
|
|
|
public function finish() {
|
|
|
|
if( !$this->zip->close() ) {
|
2013-02-11 16:44:02 +00:00
|
|
|
OC_Log::write( 'migration',
|
|
|
|
'Failed to write the zip file with error: '.$this->zip->getStatusString(),
|
|
|
|
OC_Log::ERROR );
|
2012-08-29 06:38:33 +00:00
|
|
|
return false;
|
2012-03-19 20:44:20 +00:00
|
|
|
}
|
|
|
|
$this->cleanup();
|
2012-08-29 06:38:33 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-03-19 20:44:20 +00:00
|
|
|
/**
|
2014-05-19 15:50:53 +00:00
|
|
|
* cleans up after the zip
|
2012-03-19 20:44:20 +00:00
|
|
|
*/
|
2012-09-07 13:22:01 +00:00
|
|
|
private function cleanup() {
|
2012-03-19 20:44:20 +00:00
|
|
|
// Delete tmp files
|
2012-09-07 13:22:01 +00:00
|
|
|
foreach($this->tmpfiles as $i) {
|
2012-08-29 06:38:33 +00:00
|
|
|
unlink( $i );
|
|
|
|
}
|
2012-03-19 20:44:20 +00:00
|
|
|
}
|
2012-04-14 16:31:37 +00:00
|
|
|
}
|