BackWPup – WordPress Backup Plugin - Version 3.0.6

Version Description

= After an upgrade from version 2 =

Please check all settings after the update:

  • Dropbox authentication must be done again
  • SugarSync authentication must be done again
  • S3 Settings
  • Google Storage is now in S3
  • Check all your passwords
Download this release

Release Info

Developer danielhuesken
Plugin Icon 128x128 BackWPup – WordPress Backup Plugin
Version 3.0.6
Comparing to
See all releases

Code changes from version 3.0.5 to 3.0.6

backwpup.php CHANGED
@@ -5,7 +5,7 @@
5
  * Description: WordPress Backup and more...
6
  * Author: Inpsyde GmbH
7
  * Author URI: http://inpsyde.com
8
- * Version: 3.0.5
9
  * Text Domain: backwpup
10
  * Domain Path: /languages/
11
  * Network: true
5
  * Description: WordPress Backup and more...
6
  * Author: Inpsyde GmbH
7
  * Author URI: http://inpsyde.com
8
+ * Version: 3.0.6
9
  * Text Domain: backwpup
10
  * Domain Path: /languages/
11
  * Network: true
inc/class-cron.php CHANGED
@@ -156,8 +156,7 @@ class BackWPup_Cron {
156
  *
157
  * Get the local time timestamp of the next cron execution
158
  *
159
- * @param string $cronstring string of cron (* * * * *)
160
- *
161
  * @return int timestamp
162
  */
163
  public static function cron_next( $cronstring ) {
@@ -284,7 +283,7 @@ class BackWPup_Cron {
284
  }
285
 
286
  //calc next timestamp
287
- $current_timestamp = time();
288
  foreach ( $cron[ 'year' ] as $year ) {
289
  foreach ( $cron[ 'mon' ] as $mon ) {
290
  foreach ( $cron[ 'mday' ] as $mday ) {
156
  *
157
  * Get the local time timestamp of the next cron execution
158
  *
159
+ * @param string $cronstring cron (* * * * *)
 
160
  * @return int timestamp
161
  */
162
  public static function cron_next( $cronstring ) {
283
  }
284
 
285
  //calc next timestamp
286
+ $current_timestamp = current_time( 'timestamp' );
287
  foreach ( $cron[ 'year' ] as $year ) {
288
  foreach ( $cron[ 'mon' ] as $mon ) {
289
  foreach ( $cron[ 'mday' ] as $mday ) {
inc/class-destination-dropbox.php CHANGED
@@ -495,29 +495,36 @@ final class BackWPup_Destination_Dropbox_API {
495
  if ( ! is_readable( $file ) or ! is_file( $file ) )
496
  throw new BackWPup_Destination_Dropbox_API_Exception( "Error: File \"$file\" is not readable or doesn't exist." );
497
 
498
- $file_handel = fopen( $file, 'r' );
499
- $uploadid = NULL;
500
- $offset = 0;
501
  $job_object = BackWPup_Job::getInstance();
502
-
 
 
 
 
 
 
 
503
  while ( $data = fread( $file_handel, 4194304 ) ) { //4194304 = 4MB
504
- $chunkHandle = fopen( 'php://temp', 'rw' );
505
  fwrite( $chunkHandle, $data );
506
  rewind( $chunkHandle );
507
  $url = self::API_CONTENT_URL . self::API_VERSION_URL . 'chunked_upload';
508
- $output = $this->request( $url, array( 'upload_id' => $uploadid, 'offset' => $offset ), 'PUT', $chunkHandle, strlen( $data ) );
509
- fclose( $chunkHandle );
510
- $job_object->curl_read_callback( NULL, NULL, strlen( $data ) );
511
  //args for next chunk
512
- $offset = $output[ 'offset' ];
513
- $uploadid = $output[ 'upload_id' ];
514
- fseek( $file_handel, $offset );
 
 
 
 
515
  }
516
 
517
  fclose( $file_handel );
518
  $url = self::API_CONTENT_URL . self::API_VERSION_URL . 'commit_chunked_upload/' . $this->root . '/' . $this->encode_path( $path );
519
 
520
- return $this->request( $url, array( 'overwrite' => ( $overwrite ) ? 'true' : 'false', 'upload_id' => $uploadid ), 'POST' );
521
  }
522
 
523
  /**
@@ -724,7 +731,12 @@ final class BackWPup_Destination_Dropbox_API {
724
  }
725
  //redo request
726
  return $this->request( $url, $args, $method, $filehandel, $filesize, $echo );
727
- } elseif ( $status[ 'http_code' ] == 404 ) {
 
 
 
 
 
728
  trigger_error( '(' . $status[ 'http_code' ] . ') ' . $output[ 'error' ], E_USER_WARNING );
729
 
730
  return FALSE;
495
  if ( ! is_readable( $file ) or ! is_file( $file ) )
496
  throw new BackWPup_Destination_Dropbox_API_Exception( "Error: File \"$file\" is not readable or doesn't exist." );
497
 
 
 
 
498
  $job_object = BackWPup_Job::getInstance();
499
+ $file_handel = fopen( $file, 'r' );
500
+ if ( ! isset( $job_object->steps_data[ $job_object->step_working ][ 'uploadid' ] ) )
501
+ $job_object->steps_data[ $job_object->step_working ][ 'uploadid' ] = NULL;
502
+ if ( ! isset( $job_object->steps_data[ $job_object->step_working ][ 'offset' ] ) )
503
+ $job_object->steps_data[ $job_object->step_working ][ 'offset' ] = 0;
504
+ //seek to current position
505
+ fseek( $file_handel, $job_object->steps_data[ $job_object->step_working ][ 'offset' ] );
506
+
507
  while ( $data = fread( $file_handel, 4194304 ) ) { //4194304 = 4MB
508
+ $chunkHandle = fopen( 'php://temp/maxmemory:4200000', 'r+' );
509
  fwrite( $chunkHandle, $data );
510
  rewind( $chunkHandle );
511
  $url = self::API_CONTENT_URL . self::API_VERSION_URL . 'chunked_upload';
512
+ $output = $this->request( $url, array( 'upload_id' => $job_object->steps_data[ $job_object->step_working ][ 'uploadid' ], 'offset' => $job_object->steps_data[ $job_object->step_working ][ 'offset' ] ), 'PUT', $chunkHandle, strlen( $data ) );
513
+ fclose( $chunkHandle );
 
514
  //args for next chunk
515
+ $job_object->steps_data[ $job_object->step_working ][ 'offset' ] = $output[ 'offset' ];
516
+ $job_object->steps_data[ $job_object->step_working ][ 'uploadid' ] = $output[ 'upload_id' ];
517
+ if ( $job_object->job[ 'backuptype' ] == 'archive' )
518
+ $job_object->substeps_done = $job_object->steps_data[ $job_object->step_working ][ 'offset' ];
519
+ $job_object->update_working_data();
520
+ //correct position
521
+ fseek( $file_handel, $job_object->steps_data[ $job_object->step_working ][ 'offset' ] );
522
  }
523
 
524
  fclose( $file_handel );
525
  $url = self::API_CONTENT_URL . self::API_VERSION_URL . 'commit_chunked_upload/' . $this->root . '/' . $this->encode_path( $path );
526
 
527
+ return $this->request( $url, array( 'overwrite' => ( $overwrite ) ? 'true' : 'false', 'upload_id' => $job_object->steps_data[ $job_object->step_working ][ 'uploadid' ] ), 'POST' );
528
  }
529
 
530
  /**
731
  }
732
  //redo request
733
  return $this->request( $url, $args, $method, $filehandel, $filesize, $echo );
734
+ }
735
+ elseif ( $status[ 'http_code' ] == 400 && $method == 'PUT' ) { //correct offset on chunk uploads
736
+ trigger_error( '(' . $status[ 'http_code' ] . ') False offset will corrected', E_USER_NOTICE );
737
+ return $output;
738
+ }
739
+ elseif ( $status[ 'http_code' ] == 404 && ! empty( $output[ 'error' ] )) {
740
  trigger_error( '(' . $status[ 'http_code' ] . ') ' . $output[ 'error' ], E_USER_WARNING );
741
 
742
  return FALSE;
inc/class-install.php CHANGED
@@ -23,7 +23,7 @@ class BackWPup_Install {
23
  $activejobs = BackWPup_Option::get_job_ids( 'activetype', 'wpcron' );
24
  if ( ! empty( $activejobs ) ) {
25
  foreach ( $activejobs as $id ) {
26
- $cronnxet = BackWPup_Option::get( $id, 'cronnextrun' );
27
  wp_schedule_single_event( $cronnxet, 'backwpup_cron', array( 'id' => $id ) );
28
  }
29
  }
@@ -300,7 +300,7 @@ class BackWPup_Install {
300
  }
301
  $jobvalue[ 'backupuploadsexcludedirs' ] = $excludes;
302
  //delete not longer needed
303
- unset( $jobvalue[ 'fileprefix' ], $jobvalue[ 'fileformart' ], $jobvalue[ 'scheduleintervaltype' ], $jobvalue[ 'scheduleintervalteimes' ], $jobvalue[ 'scheduleinterval' ], $jobvalue[ 'dropemail' ], $jobvalue[ 'dropepass' ], $jobvalue[ 'dropesignmethod' ] );
304
  //save in options
305
  foreach ( $jobvalue as $jobvaluename => $jobvaluevalue )
306
  BackWPup_Option::update( $jobvalue[ 'jobid' ], $jobvaluename, $jobvaluevalue );
23
  $activejobs = BackWPup_Option::get_job_ids( 'activetype', 'wpcron' );
24
  if ( ! empty( $activejobs ) ) {
25
  foreach ( $activejobs as $id ) {
26
+ $cronnxet = BackWPup_Cron::cron_next( BackWPup_Option::get( $id, 'cron') );
27
  wp_schedule_single_event( $cronnxet, 'backwpup_cron', array( 'id' => $id ) );
28
  }
29
  }
300
  }
301
  $jobvalue[ 'backupuploadsexcludedirs' ] = $excludes;
302
  //delete not longer needed
303
+ unset( $jobvalue[ 'cronnextrun' ], $jobvalue[ 'fileprefix' ], $jobvalue[ 'fileformart' ], $jobvalue[ 'scheduleintervaltype' ], $jobvalue[ 'scheduleintervalteimes' ], $jobvalue[ 'scheduleinterval' ], $jobvalue[ 'dropemail' ], $jobvalue[ 'dropepass' ], $jobvalue[ 'dropesignmethod' ] );
304
  //save in options
305
  foreach ( $jobvalue as $jobvaluename => $jobvaluevalue )
306
  BackWPup_Option::update( $jobvalue[ 'jobid' ], $jobvaluename, $jobvaluevalue );
inc/class-job.php CHANGED
@@ -169,7 +169,6 @@ final class BackWPup_Job {
169
  BackWPup_Option::update( $this->job[ 'jobid' ], 'lastrun', $this->start_time );
170
  BackWPup_Option::update( $this->job[ 'jobid' ], 'logfile', $this->logfile ); //Set current logfile
171
  BackWPup_Option::update( $this->job[ 'jobid' ], 'lastbackupdownloadurl', '' );
172
- BackWPup_Option::update( $this->job[ 'jobid' ], 'cronnextrun', BackWPup_Cron::cron_next( BackWPup_Option::get( $this->job[ 'jobid' ], 'cron' ) ) );
173
  }
174
  //Set needed job values
175
  $this->timestamp_last_update = microtime( TRUE );
@@ -273,7 +272,7 @@ final class BackWPup_Job {
273
  $info .= __( '[INFO] This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions.', 'backwpup' ) . PHP_EOL;
274
  $info .= sprintf(__( '[INFO] BackWPup job: %1$s; %2$s', 'backwpup' ), esc_attr( $this->job[ 'name' ] ) , implode( '+', $this->job[ 'type' ] ) ) . PHP_EOL;
275
  if ( $this->job[ 'activetype' ] != '' )
276
- $info .= __( '[INFO] BackWPup cron:', 'backwpup' ) . ' ' . $this->job[ 'cron' ] . '; ' . date_i18n( 'D, j M Y @ H:i', $this->job[ 'cronnextrun' ] + ( get_option( 'gmt_offset' ) * 3600 ), TRUE ) . PHP_EOL;
277
  if ( $this->jobstarttype == 'cronrun' )
278
  $info .= __( '[INFO] BackWPup job started from wp-cron', 'backwpup' ) . PHP_EOL;
279
  elseif ( $this->jobstarttype == 'runnow' or $this->jobstarttype == 'runnowalt' )
169
  BackWPup_Option::update( $this->job[ 'jobid' ], 'lastrun', $this->start_time );
170
  BackWPup_Option::update( $this->job[ 'jobid' ], 'logfile', $this->logfile ); //Set current logfile
171
  BackWPup_Option::update( $this->job[ 'jobid' ], 'lastbackupdownloadurl', '' );
 
172
  }
173
  //Set needed job values
174
  $this->timestamp_last_update = microtime( TRUE );
272
  $info .= __( '[INFO] This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions.', 'backwpup' ) . PHP_EOL;
273
  $info .= sprintf(__( '[INFO] BackWPup job: %1$s; %2$s', 'backwpup' ), esc_attr( $this->job[ 'name' ] ) , implode( '+', $this->job[ 'type' ] ) ) . PHP_EOL;
274
  if ( $this->job[ 'activetype' ] != '' )
275
+ $info .= __( '[INFO] BackWPup cron:', 'backwpup' ) . ' ' . $this->job[ 'cron' ] . '; ' . date_i18n( 'D, j M Y @ H:i' ) . PHP_EOL;
276
  if ( $this->jobstarttype == 'cronrun' )
277
  $info .= __( '[INFO] BackWPup job started from wp-cron', 'backwpup' ) . PHP_EOL;
278
  elseif ( $this->jobstarttype == 'runnow' or $this->jobstarttype == 'runnowalt' )
inc/class-jobtype-dbdump.php CHANGED
@@ -41,7 +41,7 @@ class BackWPup_JobType_DBDump extends BackWPup_JobTypes {
41
  //set only wordpress tables as default
42
  $dbtables = $wpdb->get_results( 'SHOW TABLES FROM `' . DB_NAME . '`', ARRAY_N );
43
  foreach ( $dbtables as $dbtable) {
44
- if ( ! strstr( $dbtable[ 0 ], $wpdb->prefix ) )
45
  $defaults[ 'dbdumpexclude' ][] = $dbtable[ 0 ];
46
  }
47
 
41
  //set only wordpress tables as default
42
  $dbtables = $wpdb->get_results( 'SHOW TABLES FROM `' . DB_NAME . '`', ARRAY_N );
43
  foreach ( $dbtables as $dbtable) {
44
+ if ( $wpdb->prefix == substr( $dbtable[ 0 ], 0, strlen( $wpdb->prefix ) ) )
45
  $defaults[ 'dbdumpexclude' ][] = $dbtable[ 0 ];
46
  }
47
 
inc/class-page-backwpup.php CHANGED
@@ -263,8 +263,6 @@ class BackWPup_Page_BackWPup {
263
  echo "</td></tr>";
264
  }
265
  else {
266
- $cronnextrun = BackWPup_Option::get( $jobid, 'cronnextrun' );
267
- $cronnextrun = $cronnextrun + ( get_option( 'gmt_offset' ) * 3600 );
268
  if ( ! $alternate ) {
269
  echo '<tr>';
270
  $alternate = TRUE;
@@ -272,7 +270,11 @@ class BackWPup_Page_BackWPup {
272
  echo '<tr class="alternate">';
273
  $alternate = FALSE;
274
  }
275
- echo '<td>' . date_i18n( get_option( 'date_format' ), $cronnextrun, TRUE ) . '<br />' . date_i18n( get_option( 'time_format' ), $cronnextrun, TRUE ) . '</td>';
 
 
 
 
276
  echo '<td><a href="' . wp_nonce_url( network_admin_url( 'admin.php' ) . '?page=backwpupeditjob&jobid=' . $jobid, 'edit-job' ) . '" title="' . esc_attr( __( 'Edit Job', 'backwpup' ) ) . '">' . $name . '</a></td></tr>';
277
  }
278
  }
263
  echo "</td></tr>";
264
  }
265
  else {
 
 
266
  if ( ! $alternate ) {
267
  echo '<tr>';
268
  $alternate = TRUE;
270
  echo '<tr class="alternate">';
271
  $alternate = FALSE;
272
  }
273
+ if ( $nextrun = wp_next_scheduled( 'backwpup_cron', array( 'id' => $jobid ) ) + ( get_option( 'gmt_offset' ) * 3600 ) )
274
+ echo '<td>' . date_i18n( get_option( 'date_format' ), $nextrun, TRUE ) . '<br />' . date_i18n( get_option( 'time_format' ), $nextrun, TRUE ) . '</td>';
275
+ else
276
+ echo '<td><em>' . __( 'Not scheduled!', 'backwpup' ) . '</em></td>';
277
+
278
  echo '<td><a href="' . wp_nonce_url( network_admin_url( 'admin.php' ) . '?page=backwpupeditjob&jobid=' . $jobid, 'edit-job' ) . '" title="' . esc_attr( __( 'Edit Job', 'backwpup' ) ) . '">' . $name . '</a></td></tr>';
279
  }
280
  }
inc/class-page-editjob.php CHANGED
@@ -154,12 +154,10 @@ class BackWPup_Page_Editjob {
154
  if ( $_POST[ 'cronbtype' ] == 'hour' )
155
  BackWPup_Option::update( $jobid, 'cron', $_POST[ 'hourcronminutes' ] . ' * * * *' );
156
  }
157
- //Save next run time
158
- BackWPup_Option::update( $jobid, 'cronnextrun', BackWPup_Cron::cron_next( BackWPup_Option::get( $jobid, 'cron' ) ) );
159
  //reschedule
160
  wp_clear_scheduled_hook( 'backwpup_cron', array( 'id' => $jobid ) );
161
  if ( BackWPup_Option::get( $jobid, 'activetype' ) == 'wpcron' ) {
162
- $cronnxet = BackWPup_Option::get( $jobid, 'cronnextrun' );
163
  wp_schedule_single_event( $cronnxet, 'backwpup_cron', array( 'id' => $jobid ) );
164
  }
165
  break;
@@ -324,13 +322,13 @@ class BackWPup_Page_Editjob {
324
  $repeathouer = 1;
325
  echo '<span style="color:red;">' . sprintf( __( 'ATTENTION: Job runs every %d hours!', 'backwpup' ), $repeathouer ) . '</span><br />';
326
  }
327
- $nextrun = BackWPup_Cron::cron_next( $cronstamp );
328
  if ( 2147483647 == $nextrun ) {
329
  echo '<span style="color:red;">' . __( 'ATTENTION: Can\'t calculate cron!', 'backwpup' ) . '</span><br />';
330
  }
331
  else {
332
  _e( 'Next runtime:', 'backwpup' );
333
- echo ' <b>' . date_i18n( 'D, j M Y, H:i', BackWPup_Cron::cron_next( $cronstamp ) + ( get_option( 'gmt_offset' ) * 3600 ),TRUE ) . '</b>';
334
  }
335
  echo "</p>";
336
 
154
  if ( $_POST[ 'cronbtype' ] == 'hour' )
155
  BackWPup_Option::update( $jobid, 'cron', $_POST[ 'hourcronminutes' ] . ' * * * *' );
156
  }
 
 
157
  //reschedule
158
  wp_clear_scheduled_hook( 'backwpup_cron', array( 'id' => $jobid ) );
159
  if ( BackWPup_Option::get( $jobid, 'activetype' ) == 'wpcron' ) {
160
+ $cronnxet = BackWPup_Cron::cron_next( BackWPup_Option::get( $jobid, 'cron' ) );
161
  wp_schedule_single_event( $cronnxet, 'backwpup_cron', array( 'id' => $jobid ) );
162
  }
163
  break;
322
  $repeathouer = 1;
323
  echo '<span style="color:red;">' . sprintf( __( 'ATTENTION: Job runs every %d hours!', 'backwpup' ), $repeathouer ) . '</span><br />';
324
  }
325
+ $nextrun = BackWPup_Cron::cron_next( $cronstamp ) + ( get_option( 'gmt_offset' ) * 3600 );
326
  if ( 2147483647 == $nextrun ) {
327
  echo '<span style="color:red;">' . __( 'ATTENTION: Can\'t calculate cron!', 'backwpup' ) . '</span><br />';
328
  }
329
  else {
330
  _e( 'Next runtime:', 'backwpup' );
331
+ echo ' <b>' . date_i18n( 'D, j M Y, H:i', $nextrun, TRUE ) . '</b>';
332
  }
333
  echo "</p>";
334
 
inc/class-page-jobs.php CHANGED
@@ -191,13 +191,10 @@ class BackWPup_Page_Jobs extends WP_List_Table {
191
  if ( is_object( $job_object ) && $job_object->job[ 'jobid' ] == $jobid )
192
  $r .='<div class="job-normal"' . $job_normal_hide . '>';
193
  if ( BackWPup_Option::get( $jobid, 'activetype' ) == 'wpcron' ) {
194
- if ( $nextrun = wp_next_scheduled( 'backwpup_cron', array( 'id' => $jobid ) ) ) {
195
- $nextrun = $nextrun + get_option( 'gmt_offset' ) * 3600;
196
  $r .= '<span title="' . sprintf( __( 'Cron: %s','backwpup'),BackWPup_Option::get( $jobid, 'cron' ) ). '">' . sprintf( __( '%1$s at %2$s by WP-Cron', 'backwpup' ) , date_i18n( get_option( 'date_format' ), $nextrun, TRUE ) , date_i18n( get_option( 'time_format' ), $nextrun, TRUE ) ) . '</span>';
197
- }
198
- else {
199
  $r .= __( 'Not scheduled!', 'backwpup' );
200
- }
201
  }
202
  else {
203
  $r .= __( 'Inactive', 'backwpup' );
@@ -277,7 +274,7 @@ class BackWPup_Page_Jobs extends WP_List_Table {
277
  if ( $key == "archivename" )
278
  $option = str_replace( $_GET[ 'jobid' ], $newjobid, $option );
279
  if ( $key == "logfile" || $key == "lastbackupdownloadurl" || $key == "lastruntime" ||
280
- $key == "lastrun" || $key == "cronnextrun" )
281
  continue;
282
  BackWPup_Option::update( $newjobid, $key, $option );
283
  }
191
  if ( is_object( $job_object ) && $job_object->job[ 'jobid' ] == $jobid )
192
  $r .='<div class="job-normal"' . $job_normal_hide . '>';
193
  if ( BackWPup_Option::get( $jobid, 'activetype' ) == 'wpcron' ) {
194
+ if ( $nextrun = wp_next_scheduled( 'backwpup_cron', array( 'id' => $jobid ) ) + ( get_option( 'gmt_offset' ) * 3600 ) )
 
195
  $r .= '<span title="' . sprintf( __( 'Cron: %s','backwpup'),BackWPup_Option::get( $jobid, 'cron' ) ). '">' . sprintf( __( '%1$s at %2$s by WP-Cron', 'backwpup' ) , date_i18n( get_option( 'date_format' ), $nextrun, TRUE ) , date_i18n( get_option( 'time_format' ), $nextrun, TRUE ) ) . '</span>';
196
+ else
 
197
  $r .= __( 'Not scheduled!', 'backwpup' );
 
198
  }
199
  else {
200
  $r .= __( 'Inactive', 'backwpup' );
274
  if ( $key == "archivename" )
275
  $option = str_replace( $_GET[ 'jobid' ], $newjobid, $option );
276
  if ( $key == "logfile" || $key == "lastbackupdownloadurl" || $key == "lastruntime" ||
277
+ $key == "lastrun" )
278
  continue;
279
  BackWPup_Option::update( $newjobid, $key, $option );
280
  }
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
- === BackWPup ===
2
  Contributors: inpsyde, danielhuesken, Bueltge, nullbyte
3
  Tags: backup, dump, database, file, ftp, xml, time, upload, multisite, cloud, dropbox, storage, S3
4
  Requires at least: 3.2
5
  Tested up to: 3.5.1
6
- Stable tag: 3.0.5
7
  License: GPLv3
8
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
9
 
@@ -179,6 +179,11 @@ Please check all settings after the update:
179
 
180
 
181
  == Changelog ==
 
 
 
 
 
182
  = Version 3.0.5 =
183
  * Changed: Display only normal messages on progress bars
184
  * Changed: Detection of multisite blog upload folder
1
+ === BackWPup ===
2
  Contributors: inpsyde, danielhuesken, Bueltge, nullbyte
3
  Tags: backup, dump, database, file, ftp, xml, time, upload, multisite, cloud, dropbox, storage, S3
4
  Requires at least: 3.2
5
  Tested up to: 3.5.1
6
+ Stable tag: 3.0.6
7
  License: GPLv3
8
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
9
 
179
 
180
 
181
  == Changelog ==
182
+ = Version 3.0.6 =
183
+ * Fixed: Massages on empty DB prefix
184
+ * Fixed: Bug in cron calculation
185
+ * Improved: Dropbox upload so that it can continuing on next try
186
+
187
  = Version 3.0.5 =
188
  * Changed: Display only normal messages on progress bars
189
  * Changed: Detection of multisite blog upload folder