Plugin Directory

Changeset 2781798


Ignore:
Timestamp:
09/08/2022 08:13:25 AM (4 years ago)
Author:
ploudapp
Message:

New version published 1.0.3

Location:
pcloud-wp-backup
Files:
26 added
10 edited

Legend:

Unmodified
Added
Removed
  • pcloud-wp-backup/trunk/assets/css/wpb2pcloud.css

    r2732482 r2781798  
    121121}
    122122
    123 #setting-error-settings_updated {
     123#setting-error-settings_updated,
     124#setting-error-mysql-settings_updated {
    124125    display: none;
    125126    margin: 0 0 10px;
  • pcloud-wp-backup/trunk/assets/js/wp2pcl.js

    r2732482 r2781798  
    137137            );
    138138        }
     139
     140        /**
     141         * SET INCLUDE DATABASE IN THE BACKUP ->
     142         * SET INCLUDE DATABASE IN THE BACKUP ->
     143         */
     144        $( '#wp2pcl_withmysql' ).on(
     145            'change',
     146            function ( e ) {
     147                e.preventDefault();
     148                $( '#setting-error-mysql-settings_updated' ).show();
     149                $.post(
     150                    ajax_url + '&method=set_with_mysql',
     151                    $( '#wp2_incl_db_form' ).serialize(),
     152                    function () {
     153                        $.get( 'admin.php' );
     154                    },
     155                    'JSON'
     156                );
     157            }
     158        );
    139159
    140160        /**
     
    264284        let backupLogWin = $( '.log_show' );
    265285
    266         function pclCheckActivity()
     286        function pclCheckActivity( recheck )
    267287        {
    268288            $.ajax(
     
    397417            ).always(
    398418                function () {
    399                     window.setTimeout(
    400                         function () {
    401                             pclCheckActivity();
    402                         },
    403                         log_reader_timer
    404                     );
     419                    if ( typeof recheck !== "undefined" && recheck ) {
     420                        window.setTimeout(
     421                            function () {
     422                                pclCheckActivity( true );
     423                            },
     424                            log_reader_timer
     425                        );
     426                    }
    405427                }
    406428            );
     
    408430        }
    409431
    410         pclCheckActivity();
     432        pclCheckActivity( true );
    411433
    412434        /**
     
    441463                    wp2pcl_debugmode = true;
    442464                    btn.css( 'color', '#333' );
     465                    pclCheckActivity();
    443466                    backupLogWin.show();
    444467                }
  • pcloud-wp-backup/trunk/classes/class-pcl-mysqldump.php

    r2731122 r2781798  
    2525     * File handler
    2626     *
    27      * @var null $file_handler
     27     * @var null|resource $file_handler
    2828     */
    2929    private $file_handler = null;
     
    218218
    219219        $pdo_settings_default = array(
    220             PDO::ATTR_PERSISTENT => true,
    221             PDO::ATTR_ERRMODE    => PDO::ERRMODE_EXCEPTION,
     220            PDO::ATTR_PERSISTENT => true, // phpcs:ignore
     221            PDO::ATTR_ERRMODE    => PDO::ERRMODE_EXCEPTION, // phpcs:ignore
    222222        );
    223223
     
    228228        // This drops MYSQL dependency, only use the constant if it's defined.
    229229        if ( 'mysql' === $this->db_type ) {
    230             $pdo_settings_default[ PDO::MYSQL_ATTR_USE_BUFFERED_QUERY ] = false;
     230            $pdo_settings_default[ PDO::MYSQL_ATTR_USE_BUFFERED_QUERY ] = false; // phpcs:ignore
    231231        }
    232232
     
    351351
    352352        try {
    353             $this->db_handler = new PDO(
     353            $this->db_handler = new PDO( // phpcs:ignore
    354354                $this->dsn,
    355355                $this->user,
     
    368368        }
    369369
    370         $this->db_handler->setAttribute( PDO::ATTR_ORACLE_NULLS, PDO::NULL_NATURAL );
     370        $this->db_handler->setAttribute( PDO::ATTR_ORACLE_NULLS, PDO::NULL_NATURAL ); // phpcs:ignore
    371371        $this->type_adapter = Pcl_Type_Adapter_Mysql::create( $this->db_handler, $this->dump_settings );
    372372    }
     
    713713            $this->type_adapter->show_columns( $table_name )
    714714        );
    715         $columns->setFetchMode( PDO::FETCH_ASSOC );
     715        $columns->setFetchMode( PDO::FETCH_ASSOC ); // phpcs:ignore
    716716
    717717        foreach ( $columns as $col ) {
     
    952952
    953953        $result_set = $this->db_handler->query( $stmt );
    954         $result_set->setFetchMode( PDO::FETCH_ASSOC );
     954        $result_set->setFetchMode( PDO::FETCH_ASSOC ); // phpcs:ignore
    955955
    956956        $ignore = $this->dump_settings['insert-ignore'] ? '  IGNORE' : '';
     
    11241124     */
    11251125    public function compress_open( $file_name ) {
    1126         $this->file_handler = fopen( $file_name, 'wb' );
     1126        $this->file_handler = fopen( $file_name, 'wb' ); // phpcs:ignore
    11271127        if ( false === $this->file_handler ) {
    11281128            throw new Exception( 'Output file is not writable' );
     
    11401140     */
    11411141    public function compress_write( $str ) {
    1142         $bytes_written = fwrite( $this->file_handler, $str );
    1143         if ( false === $bytes_written ) {
    1144             throw new Exception( 'Writting to file failed! Probably, there is no more free space left?' );
    1145         }
    1146 
    1147         return $bytes_written;
     1142
     1143        if ( ! is_null( $this->file_handler ) ) {
     1144
     1145            $bytes_written = fwrite( $this->file_handler, $str ); // phpcs:ignore
     1146            if ( false === $bytes_written ) {
     1147                throw new Exception( 'Writting to file failed! Probably, there is no more free space left?' );
     1148            }
     1149
     1150            return $bytes_written;
     1151        } else {
     1152            return 0;
     1153        }
    11481154    }
    11491155
     
    11541160     */
    11551161    public function compress_close() {
    1156         return fclose( $this->file_handler );
     1162        if ( ! is_null( $this->file_handler ) ) {
     1163            return fclose( $this->file_handler ); // phpcs:ignore
     1164        } else {
     1165            return false;
     1166        }
    11571167    }
    11581168}
  • pcloud-wp-backup/trunk/classes/class-wp2pclouddebugger.php

    r2732482 r2781798  
    5757
    5858        $current_data = WP2pCloudFuncs::get_storred_val( PCLOUD_DBG_LOG );
     59        $mem_usage    = WP2pCloudFuncs::memory_usage();
    5960
    6061        if ( 'uploading' === $new_data ) {
     
    6465            }
    6566        } else {
    66             $current_data .= '<br/>' . gmdate( 'Y-m-d H:i:s' ) . ' - ' . $new_data;
     67            $current_data .= '<br/>' . gmdate( 'Y-m-d H:i:s' ) . ' [' . $mem_usage . '] - ' . $new_data;
    6768        }
    6869
     
    7071
    7172    }
    72 
    73     /**
    74      * Clear log method, clears the log data
    75      *
    76      * @return void
    77      */
    78     public static function clear_log() {
    79         WP2pCloudFuncs::set_storred_val( PCLOUD_DBG_LOG, '' );
    80     }
    8173}
  • pcloud-wp-backup/trunk/classes/class-wp2pcloudfilebackup.php

    r2732482 r2781798  
    6161    public function __construct( $base_dir ) {
    6262
    63         $this->sql_backup_file = false;
     63        $this->sql_backup_file = '';
    6464        $this->base_dir        = $base_dir;
    6565        $this->authkey         = WP2pCloudFuncs::get_storred_val( PCLOUD_AUTH_KEY );
     
    127127
    128128        $this->clear_all_tmp_files();
     129
    129130        WP2pCloudDebugger::log( 'All temporary files - cleared!' );
    130131
    131132        $rootdir = rtrim( ABSPATH, '/' );
    132133
    133         $dirs = self::find_all_files( $rootdir );
    134         WP2pCloudDebugger::log( 'All files collected and ready to be compressed!' );
    135         WP2pCloudDebugger::log( 'Start creating ZIP archive!' );
    136 
    137         $this->create_zip( $dirs, $backup_file_name );
    138 
    139         WP2pCloudDebugger::log( 'ZIP archive - READY!' );
     134        WP2pCloudDebugger::log( 'Creating a list of files to be compressed!' );
     135
     136        $files = self::find_all_files( $rootdir );
     137
     138        WP2pCloudDebugger::log( 'The List of all files is ready and will be sent for compression!' );
     139
     140        $php_extensions            = get_loaded_extensions();
     141        $has_archive_ext_installed = array_search( 'zip', $php_extensions, true );
     142
     143        if ( $has_archive_ext_installed ) {
     144
     145            WP2pCloudDebugger::log( 'Start creating ZIP archive!' );
     146
     147            for ( $try = 0; $try < 2; $try++ ) {
     148
     149                WP2pCloudDebugger::log( 'Attempt [ ' . ( $try + 1 ) . ' ] to create the ZIP archive!' );
     150
     151                $zipping_successfull = $this->create_zip( $files, $backup_file_name );
     152                if ( $zipping_successfull ) {
     153                    break;
     154                }
     155            }
     156
     157            if ( ! $zipping_successfull ) {
     158
     159                WP2pCloudFuncs::set_operation( array() );
     160
     161                WP2pCloudLogger::info( '<span>ERROR: Failed to create backup ZIP file !</span>' );
     162                WP2pCloudDebugger::log( 'Failed to create valid ZIP archive after all 5 tries!' );
     163
     164            } else {
     165
     166                sleep( 3 );
     167
     168                try {
     169
     170                    WP2pCloudDebugger::log( 'Archive seems ready, trying to validate it!' );
     171
     172                    $this->validate_zip_archive( $backup_file_name );
     173
     174                    WP2pCloudDebugger::log( 'Zip Archive - seems valid!' );
     175
     176                } catch ( Exception $e ) {
     177
     178                    WP2pCloudLogger::info( '<span>ERROR: Backup archive not valid!</span>' );
     179                    WP2pCloudDebugger::log( 'Invalid backup file detected, error: ' . $e->getMessage() . ' file: ' . $backup_file_name );
     180
     181                    WP2pCloudFuncs::set_operation( array() );
     182
     183                    exit();
     184                }
     185            }
     186        } else {
     187
     188            WP2pCloudLogger::info( "<span class='pcl_transl' data-i10nk='err_backup_arch_no_file'>ERROR: Backup archive file don't exist!</span>" );
     189            WP2pCloudDebugger::log( 'Backup file does not exist! PHP Zip extension is missing!' );
     190
     191            WP2pCloudFuncs::set_operation( array() );
     192
     193            exit();
     194        }
     195
     196        WP2pCloudDebugger::log( 'Archiving process - COMPLETED!' );
    140197
    141198        WP2pCloudLogger::info( "<span class='pcl_transl' data-i10nk='zip_file_created'>Zip file is created! Uploading to pCloud</span>" );
     
    154211
    155212        if ( ! file_exists( $backup_file_name ) ) {
     213
    156214            WP2pCloudLogger::info( "<span class='pcl_transl' data-i10nk='err_backup_arch_no_file'>ERROR: Backup archive file don't exist!</span>" );
    157             WP2pCloudDebugger::log( 'Backup file does not exist!' );
     215            WP2pCloudDebugger::log( 'Backup file does not exist, quiting... !' );
     216
     217            WP2pCloudFuncs::set_operation( array() );
     218
    158219        } else {
    159220
     
    238299     * @param string $backup_file_name Backup file name.
    239300     *
    240      * @return void
     301     * @return bool
    241302     */
    242303    private function create_zip( $files, $backup_file_name ) {
     
    245306
    246307        $zip = new ZipArchive();
    247         $zip->open( $backup_file_name, ZIPARCHIVE::CREATE );
    248         WP2pCloudDebugger::log( 'ZIP state - open' );
    249         $zip->setArchiveComment( 'Wordpress2pCloud' );
    250 
    251         foreach ( $files as $el ) {
    252             $zip->addFile( $el, str_replace( ABSPATH, '', $el ) );
    253         }
    254 
    255         WP2pCloudDebugger::log( 'ZIP files added' );
    256 
    257         if ( false !== $this->sql_backup_file ) {
    258             $zip->addFile( $this->sql_backup_file, 'backup.sql' );
    259         }
    260 
    261         WP2pCloudDebugger::log( 'ZIP DB file - added' );
     308        if ( true !== $zip->open( $backup_file_name, ZIPARCHIVE::CREATE ) ) {
     309
     310            $zip->close();
     311            $zip = null;
     312
     313            WP2pCloudDebugger::log( 'ZIP state - failed to create the ZIP file, leaving ...!' );
     314
     315            return false;
     316        }
     317
     318        WP2pCloudDebugger::log( 'ZIP state - opened!' );
     319
     320        $zip->setArchiveComment( 'Wordpress2pCloud-' . gmdate( 'd.m.Y H:i:s' ) );
     321
     322        foreach ( $files as $file ) {
     323            if ( file_exists( $file ) && is_readable( $file ) ) {
     324                $zip->addFile( $file, str_replace( ABSPATH, '', $file ) );
     325            }
     326        }
     327
     328        WP2pCloudDebugger::log( 'ZIP entries added [ ' . count( $files ) . ' ] ' );
     329
     330        if ( ! empty( $this->sql_backup_file ) ) {
     331            if ( file_exists( $this->sql_backup_file ) && is_readable( $this->sql_backup_file ) ) {
     332                $zip->addFile( $this->sql_backup_file, 'backup.sql' );
     333                WP2pCloudDebugger::log( 'ZIP DB file - added!' );
     334            }
     335        }
     336
     337        WP2pCloudDebugger::log( 'ZIP archive - filling-up and closing ' );
    262338
    263339        if ( $zip->close() ) {
    264340
    265             $size = $this->format_bytes( filesize( $backup_file_name ) );
    266 
    267             WP2pCloudLogger::info( "<span class='pcl_transl' data-i10nk='backup_file_size'>Backup file size:</span> (" . $size . ')' );
     341            $size = WP2pCloudFuncs::format_bytes( filesize( $backup_file_name ) );
     342
     343            WP2pCloudLogger::info( "<span class='pcl_transl' data-i10nk='backup_file_size'>Backup file size:</span> ( $size )" );
    268344            WP2pCloudDebugger::log( 'ZIP File successfully closed! [ ' . $size . ' ]' );
    269345
    270         } else {
    271 
    272             $status = $zip->getStatusString();
    273 
    274             WP2pCloudLogger::info( "<span class='pcl_transl' data-i10nk='err_failed2zip'>Error: failed to create zip archive [ '. $status . ' ]</span>" );
    275             WP2pCloudFuncs::set_operation( array() );
    276 
    277             WP2pCloudDebugger::log( '--------- |||| -------- Failed to create ZIP file: ' . $status );
    278 
    279             exit();
    280         }
    281 
     346            $zip = null;
     347
     348            return true;
     349
     350        } else {
     351
     352            WP2pCloudLogger::info( "<span class='pcl_transl' data-i10nk='err_failed2zip'>Error: failed to create zip archive!</span>" );
     353            WP2pCloudDebugger::log( '--------- |||| -------- Failed to create ZIP file!' );
     354
     355            $zip = null;
     356        }
     357
     358        return false;
    282359    }
    283360
     
    388465    public function upload_chunk( $path, $folder_id = 0, $upload_id = 0, $uploadoffset = 0, $num_failures = 0 ) {
    389466
     467        $filesize = abs( filesize( $path ) );
     468
     469        $this->set_chunk_size( $filesize );
     470
    390471        if ( ! file_exists( $path ) || ! is_file( $path ) || ! is_readable( $path ) ) {
    391472            WP2pCloudLogger::info( "<span class='pcl_transl' data-i10nk='invalid_file_provided'>Invalid file provided!</span>" );
     
    394475        }
    395476
    396         $filesize = abs( filesize( $path ) );
    397 
    398477        if ( $uploadoffset > $filesize ) {
    399478            WP2pCloudLogger::info( "<span class='pcl_transl' data-i10nk='wp_all_done'>All Done!</span>" );
     
    408487
    409488        // Complicated file operations, currently not supported by: WP_Filesystem.
    410         $file = fopen( $path, 'r' );
     489        $file = fopen( $path, 'r' ); // phpcs:ignore
    411490
    412491        if ( $uploadoffset > 0 ) {
    413             fseek( $file, $uploadoffset );
    414         }
    415         $content = fread( $file, $this->part_size );
     492            fseek( $file, $uploadoffset ); // phpcs:ignore
     493        }
     494        $content = fread( $file, $this->part_size ); // phpcs:ignore
    416495        try {
    417496            if ( ! empty( $content ) ) {
     
    436515                }
    437516            }
    438             fclose( $file );
     517            fclose( $file ); // phpcs:ignore
    439518
    440519            if ( $uploadoffset > $filesize ) {
     
    451530            }
    452531        } catch ( Exception $e ) {
    453             fclose( $file );
     532            fclose( $file ); // phpcs:ignore
    454533        }
    455534
     
    478557        } else {
    479558            $filesize = abs( filesize( $path ) );
     559
     560            $this->set_chunk_size( $filesize );
    480561        }
    481562
     
    495576        $num_failures = 0;
    496577
    497         $file = fopen( $path, 'r' );
     578        $file = fopen( $path, 'r' ); // phpcs:ignore
    498579        while ( ! feof( $file ) ) {
    499             $content = fread( $file, $this->part_size );
     580            $content = fread( $file, $this->part_size ); // phpcs:ignore
    500581            do {
    501582                try {
     
    542623        }
    543624
    544         fclose( $file );
     625        fclose( $file ); // phpcs:ignore
    545626
    546627        if ( $uploadoffset >= $filesize ) {
     
    671752                        $err_message = trim( $response_json['error'] );
    672753                    } else {
    673                         WP2pCloudDebugger::log( 'write() - unexpected msg returned: ' . print_r( $response_json, true ) );
     754                        WP2pCloudDebugger::log( 'write() - unexpected msg returned: ' . wp_json_encode( $response_json ) );
    674755                    }
    675756                }
     
    689770
    690771    /**
    691      * Format bytes to human-readable format
    692      *
    693      * @param string|int $bytes Bytes to be made more human-readable.
    694      *
    695      * @return string
    696      */
    697     private function format_bytes( $bytes ) {
    698         $size   = array( 'B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' );
    699         $factor = floor( ( strlen( $bytes ) - 1 ) / 3 );
    700 
    701         return sprintf( '%.2f', $bytes / pow( 1024, $factor ) ) . $size[ $factor ];
     772     * Validate the ZIP archive.
     773     *
     774     * @param string $file Filename to test.
     775     *
     776     * @return void
     777     * @throws Exception Throws exception if issue is detected.
     778     */
     779    private function validate_zip_archive( $file ) {
     780
     781        $zip          = new ZipArchive();
     782        $open_archive = $zip->open( $file, ZIPARCHIVE::CHECKCONS );
     783
     784        if ( is_bool( $open_archive ) && ! $open_archive ) {
     785
     786            if ( ! is_null( $zip ) ) {
     787                $zip->close();
     788            }
     789            $zip = null;
     790
     791            throw new Exception( 'error opening zip for validation!' );
     792
     793        } elseif ( is_bool( $open_archive ) ) {
     794
     795            if ( ! is_null( $zip ) ) {
     796                $zip->close();
     797            }
     798            $zip = null;
     799        }
     800
     801        switch ( $open_archive ) {
     802
     803            case ZipArchive::ER_MULTIDISK:
     804            case ZipArchive::ER_OK:
     805                break;
     806
     807            case ZipArchive::ER_NOZIP:
     808                throw new Exception( 'not a zip archive' );
     809            case ZipArchive::ER_INCONS:
     810                throw new Exception( 'zip archive inconsistent' );
     811            case ZipArchive::ER_CRC:
     812                throw new Exception( 'checksum failed' );
     813            case ZipArchive::ER_INTERNAL:
     814                throw new Exception( 'internal error' );
     815            case ZipArchive::ER_EOF:
     816                throw new Exception( 'premature EOF' );
     817            case ZipArchive::ER_CHANGED:
     818                throw new Exception( 'entry has been changed' );
     819            case ZipArchive::ER_MEMORY:
     820                throw new Exception( 'memory allocation failure' );
     821            case ZipArchive::ER_ZLIB:
     822                throw new Exception( 'zlib error' );
     823            case ZipArchive::ER_TMPOPEN:
     824                throw new Exception( 'failure to create temporary file.' );
     825            case ZipArchive::ER_OPEN:
     826                throw new Exception( 'can\'t open file' );
     827            case ZipArchive::ER_SEEK:
     828                throw new Exception( 'seek error' );
     829            case ZipArchive::ER_NOENT:
     830                throw new Exception( 'ZIP file not found!' );
     831
     832            default:
     833                throw new Exception( 'unknown error occured: ' . $open_archive );
     834        }
     835
     836        if ( ! is_null( $zip ) ) {
     837            $zip->close();
     838        }
     839        $zip = null;
     840    }
     841
     842    /**
     843     * Set chunk size, based on the archive size.
     844     *
     845     * @param int $filesize ZIP Archive file.
     846     * @return void
     847     */
     848    public function set_chunk_size( $filesize ) {
     849
     850        if ( ! is_numeric( $filesize ) ) {
     851            return;
     852        }
     853
     854        if ( $filesize > ( 100 * 1000 * 1000 ) ) { // If Archive size is higher than 100MB.
     855            $this->part_size = 10 * 1000 * 1000;
     856        }
    702857    }
    703858}
  • pcloud-wp-backup/trunk/classes/class-wp2pcloudfilerestore.php

    r2732482 r2781798  
    7777        } else {
    7878
    79             $o_handle = fopen( $archive_file, 'ab' );
     79            $o_handle = fopen( $archive_file, 'ab' ); // phpcs:ignore
    8080            if ( ! $o_handle ) {
    8181
     
    8585                return $offset;
    8686            } else {
    87                 fwrite( $o_handle, $content );
    88             }
    89 
    90             fclose( $o_handle );
     87                fwrite( $o_handle, $content ); // phpcs:ignore
     88            }
     89
     90            fclose( $o_handle ); // phpcs:ignore
    9191
    9292            $offset += $chunksize;
     
    153153        if ( ! is_file( $sql ) ) {
    154154
    155             WP2pCloudLogger::info( "<span class='pcl_transl' data-i10nk='failed2restore_db'>Failed to restore Database, backup.sql not found in the archive!</span>" );
    156155            WP2pCloudDebugger::log( 'restore->restore_db() - Failed to restore Database, backup.sql not found in the archive!' );
    157156            return;
     
    167166
    168167            $dns = 'mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=' . DB_CHARSET;
    169             $db  = new PDO(
     168            $db  = new PDO( // phpcs:ignore
    170169                $dns,
    171170                DB_USER,
    172171                DB_PASSWORD,
    173172                array(
    174                     PDO::ATTR_EMULATE_PREPARES   => false,
    175                     PDO::ATTR_PERSISTENT         => false,
    176                     PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    177                     PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
     173                    PDO::ATTR_EMULATE_PREPARES   => false, // phpcs:ignore
     174                    PDO::ATTR_PERSISTENT         => false, // phpcs:ignore
     175                    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // phpcs:ignore
     176                    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION, // phpcs:ignore
    178177                )
    179178            );
  • pcloud-wp-backup/trunk/classes/class-wp2pcloudfuncs.php

    r2731122 r2781798  
    155155    }
    156156
     157    /**
     158     * Format bytes to human-readable format
     159     *
     160     * @param string|int $bytes Bytes to be made more human-readable.
     161     *
     162     * @return string
     163     */
     164    public static function format_bytes( $bytes ) {
     165        $size   = array( 'B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' );
     166        $factor = floor( ( strlen( $bytes ) - 1 ) / 3 );
     167
     168        return sprintf( '%.2f', $bytes / pow( 1024, $factor ) ) . $size[ $factor ];
     169    }
     170
     171    /**
     172     * Get the current memory usage allocated to this PHP process and convert it to human-readable.
     173
     174     * @return string
     175     */
     176    public static function memory_usage() {
     177
     178        $memlimitini = ini_get( 'memory_limit' );
     179
     180        $mem = memory_get_usage();
     181        if ( $mem > 0 ) {
     182            return 'mem: ' . self::format_bytes( $mem ) . '/' . $memlimitini;
     183        } else {
     184            return 'mem: --';
     185        }
     186    }
    157187}
  • pcloud-wp-backup/trunk/pcloud-wp-backup.php

    r2732482 r2781798  
    99 * Plugin URI: https://www.pcloud.com
    1010 * Summary: pCloud WP Backup plugin
    11  * Description: pCloud WP Backup has been created to make instant backups of your blog and its data, regularly. Just choose a day, time and how often you wish your backup to be saved in your pCloud! You have a lot of content on your blog such as images, videos, and comments. If your database is erased or corrupted you may lose all the information you have generated over the years. By backing up your blog, you will be able to restore everything quickly and efficiently if anything happens. Having a current backup of your WordPress blog is critical for protecting your website, so back up your files and database backups into the cloud and restore with a single click! Just create pCloud account and never worry about it again! https://www.youtube.com/watch?v=s_rDLeqr-oA&t=1s&ab_channel=pCloud
    12  * Version: 1.0.2
    13  * Author: pCloud ( Vasil Tsintsev )
     11 * Description: pCloud WP Backup has been created to make instant backups of your blog and its data, regularly.
     12 * Version: 1.0.3
     13 * Author: pCloud
    1414 * URI: https://www.pcloud.com
    1515 * License: Copyright 2013-2022 - pCloud
     
    3232    define( 'PCLOUD_SCHDATA_KEY', 'wp2pcl_schdata' );
    3333}
     34if ( ! defined( 'PCLOUD_SCHDATA_INCLUDE_MYSQL' ) ) {
     35    define( 'PCLOUD_SCHDATA_INCLUDE_MYSQL', 'wp2pcl_include_mysql' );
     36}
    3437if ( ! defined( 'PCLOUD_OPERATION' ) ) {
    3538    define( 'PCLOUD_OPERATION', 'wp2pcl_operation' );
     
    7073 * This hack will increase the wp_remote_request timeout, which otherwise dies after 5-10sec.
    7174 *
    72  * @param string|int $time input time.
    73  *
    7475 * @return int
    75  */
    76 function pcl_wb_bkup_timeout_extend( $time ) {
     76 * @noinspection PhpUnused
     77 */
     78function pcl_wb_bkup_timeout_extend() {
    7779    return 120;
    7880}
     
    102104 *
    103105 * @return void
     106 * @noinspection PhpUnused
    104107 */
    105108function backup_to_pcloud_admin_menu() {
     
    126129
    127130    $dbg_mode = false;
    128     if ( isset( $_GET['dbg'] ) && 'true' === strval( wp_unslash( $_GET['dbg'] ) ) ) {
     131    if ( isset( $_GET['dbg'] ) && 'true' === sanitize_text_field( wp_unslash( $_GET['dbg'] ) ) ) {
    129132        $dbg_mode = true;
    130133    }
     
    137140        WP2pCloudFuncs::set_storred_val( PCLOUD_USEDQUOTA, '1' );
    138141        WP2pCloudFuncs::set_storred_val( PCLOUD_API_LOCATIONID, '1' );
     142        WP2pCloudFuncs::set_storred_val( PCLOUD_SCHDATA_INCLUDE_MYSQL, '1' );
    139143
    140144        $result['status'] = 0;
    141145
    142     } elseif ( 'set_schedule' === $m ) {
     146    } elseif ( 'set_with_mysql' === $m ) {
    143147
    144148        if ( ! isset( $_POST['wp2pcl_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['wp2pcl_nonce'] ) ) ) {
     
    152156        }
    153157
     158        $withmysql = isset( $_POST['wp2pcl_withmysql'] ) ? '1' : '0';
     159
     160        WP2pCloudFuncs::set_storred_val( PCLOUD_SCHDATA_INCLUDE_MYSQL, $withmysql );
     161
     162        $result['status'] = 0;
     163
     164    } elseif ( 'set_schedule' === $m ) {
     165
     166        if ( ! isset( $_POST['wp2pcl_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['wp2pcl_nonce'] ) ) ) {
     167            $result['status']   = 15;
     168            $result['msg']      = '<p>Failed to validate the request!</p>';
     169            $result['sitename'] = $sitename;
     170
     171            echo wp_json_encode( $result );
     172
     173            return;
     174        }
     175
    154176        $freq = isset( $_POST['freq'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['freq'] ) ) ) : 't';
    155177
    156178        if ( 't' === $freq ) {
    157 
    158             add_filter(
    159                 'cron_schedules',
    160                 function ( $schedules ) {
    161                     $schedules['10_sec']  = array(
    162                         'interval' => 10,
    163                         'display'  => __( '10 seconds' ),
    164                     );
    165                     $schedules['1_hour']  = array(
    166                         'interval' => 3600,
    167                         'display'  => __( '1 hour' ),
    168                     );
    169                     $schedules['4_hours'] = array(
    170                         'interval' => 3600 * 4,
    171                         'display'  => __( '4 hours' ),
    172                     );
    173 
    174                     return $schedules;
    175                 }
    176             );
    177179
    178180            WP2pCloudDebugger::log( 'Test initiated !' );
     
    580582            } elseif ( 'download' === $operation['operation'] && 'cleanup' === $operation['state'] ) {
    581583
    582                 WP2pCloudLogger::info( "<span class='pcl_transl' data-i10nk='db_restored'>Database - restored!</span>" );
    583584                WP2pCloudLogger::info( "<span class='pcl_transl' data-i10nk='clean_up_pls_wait'>Cleaning up, please wait...</span>" );
    584585
     
    655656    WP2pCloudLogger::generate_new( "<span class='pcl_transl' data-i10nk='start_backup_at'>Start backup at</span> " . gmdate( 'Y-m-d H:i:s' ) );
    656657
    657     WP2pCloudDebugger::log( 'Database backup will start now!' );
    658     $b    = new WP2pCloudDBBackUp();
    659     $file = $b->start();
    660     WP2pCloudDebugger::log( 'Database backup - ready!' );
    661 
    662     WP2pCloudDebugger::log( 'File backup will start now!' );
    663658    $f = new WP2pCloudFileBackUp( $plugin_path_base );
    664     $f->set_mysql_backup_filename( $file );
    665     $f->start();
    666 
    667 }
    668 
    669 
    670 /**
    671  * This function performce auto-backup
    672  *
    673  * @throws Exception Standart exception will be thrown.
    674  */
    675 function wp2pcl_perform_auto_backup() {
    676 
    677     global $plugin_path_base;
    678 
    679     WP2pCloudDebugger::log( 'wp2pcl_perform_auto_backup()' );
    680 
    681     $operation = WP2pCloudFuncs::get_operation();
    682 
    683     if ( 'init' === $operation['state'] ) {
    684 
    685         WP2pCloudDebugger::log( 'wp2pcl_perform_auto_backup() - op:init !' );
    686 
    687         WP2pCloudLogger::generate_new( "<span class='pcl_transl' data-i10nk='start_auto_backup_at'>Start auto backup at</span> " . gmdate( 'Y-m-d H:i:s' ) );
    688 
     659
     660    $wp2pcl_withmysql = WP2pCloudFuncs::get_storred_val( PCLOUD_SCHDATA_INCLUDE_MYSQL );
     661    if ( ! empty( $wp2pcl_withmysql ) && 1 === intval( $wp2pcl_withmysql ) ) {
     662        WP2pCloudDebugger::log( 'Database backup will start now!' );
    689663        $b    = new WP2pCloudDBBackUp();
    690664        $file = $b->start();
     665        $f->set_mysql_backup_filename( $file );
     666
     667        WP2pCloudDebugger::log( 'Database backup - ready!' );
     668    }
     669
     670    WP2pCloudDebugger::log( 'File backup will start now!' );
     671
     672    $f->start();
     673}
     674
     675
     676/**
     677 * This function performce auto-backup
     678 *
     679 * @throws Exception Standart exception will be thrown.
     680 */
     681function wp2pcl_perform_auto_backup() {
     682
     683    global $plugin_path_base;
     684
     685    $operation = WP2pCloudFuncs::get_operation();
     686
     687    if ( 'init' === $operation['state'] ) {
     688
     689        WP2pCloudDebugger::log( 'wp2pcl_perform_auto_backup() - op:init !' );
     690
     691        WP2pCloudLogger::generate_new( "<span class='pcl_transl' data-i10nk='start_auto_backup_at'>Start auto backup at</span> " . gmdate( 'Y-m-d H:i:s' ) );
    691692
    692693        $f = new WP2pCloudFileBackUp( $plugin_path_base );
    693         $f->set_mysql_backup_filename( $file );
     694
     695        $wp2pcl_withmysql = WP2pCloudFuncs::get_storred_val( PCLOUD_SCHDATA_INCLUDE_MYSQL );
     696        if ( ! empty( $wp2pcl_withmysql ) && 1 === intval( $wp2pcl_withmysql ) ) {
     697            $b    = new WP2pCloudDBBackUp();
     698            $file = $b->start();
     699            $f->set_mysql_backup_filename( $file );
     700        }
     701
    694702        $f->start( 'auto' );
    695703
     
    723731        if ( '1_hour' === $freq ) {
    724732            if ( $lastbackupdt_tm > ( time() - 3600 ) ) {
    725                 WP2pCloudDebugger::log( 'wp2pcl_perform_auto_backup() rej: hourly' );
    726733                $rejected = true;
    727734            }
     
    729736        if ( '4_hours' === $freq ) {
    730737            if ( $lastbackupdt_tm > ( time() - ( 3600 * 4 ) ) ) {
    731                 WP2pCloudDebugger::log( 'wp2pcl_perform_auto_backup() rej: hourly' );
    732738                $rejected = true;
    733739            }
     
    735741        if ( 'daily' === $freq ) {
    736742            if ( $lastbackupdt_tm > ( time() - 86400 ) ) {
    737                 WP2pCloudDebugger::log( 'wp2pcl_perform_auto_backup() rej: daily' );
    738743                $rejected = true;
    739744            }
     
    741746        if ( 'weekly' === $freq ) {
    742747            if ( $lastbackupdt_tm > strtotime( '-1 week' ) ) {
    743                 WP2pCloudDebugger::log( 'wp2pcl_perform_auto_backup() rej: weekly' );
    744748                $rejected = true;
    745749            }
     
    747751        if ( 'monthly' === $freq ) {
    748752            if ( $lastbackupdt_tm > strtotime( '-1 month' ) ) {
    749                 WP2pCloudDebugger::log( 'wp2pcl_perform_auto_backup() rej: monthly' );
    750753                $rejected = true;
    751754            }
     
    784787        WP2pCloudFuncs::set_storred_val( 'wp2pcl_operation', $json_data );
    785788
     789        if ( ! wp_next_scheduled( 'init_autobackup' ) ) { // This will always be false.
     790            wp_schedule_event( time(), '10_sec', 'init_autobackup', array( false ) );
     791        }
    786792    } else {
    787793
     
    802808    if ( ! extension_loaded( 'zip' ) ) {
    803809        print( '<h2 style="color: red">PHP ZIP extension not loaded</h2><small>Please, contact the server administrator!</small>' );
    804 
    805810        return;
    806811    }
    807812
    808     if ( isset( $_GET['do'], $_GET['access_token'] ) && ( 'pcloud_auth' === $_GET['do'] ) && ! empty( $_GET['access_token'] ) ) {
    809 
    810         $sel_location = isset( $_GET['locationid'] ) ? intval( sanitize_key( wp_unslash( $_GET['locationid'] ) ) ) : 1;
    811         if ( $sel_location > 0 && $sel_location < 100 ) {
    812             WP2pCloudFuncs::set_storred_val( PCLOUD_API_LOCATIONID, $sel_location );
     813    $do         = '';
     814    $auth_key   = '';
     815    $locationid = 1;
     816
     817    if ( isset( $_GET['do'] ) ) { // phpcs:ignore
     818        $do = sanitize_text_field( wp_unslash( $_GET['do'] ) ); // phpcs:ignore
     819    }
     820    if ( isset( $_GET['access_token'] ) ) { // phpcs:ignore
     821        $auth_key = trim( sanitize_text_field( wp_unslash( $_GET['access_token'] ) ) ); // phpcs:ignore
     822    }
     823    if ( isset( $_GET['locationid'] ) ) { // phpcs:ignore
     824        $locationid = intval( sanitize_key( wp_unslash( $_GET['locationid'] ) ) ); // phpcs:ignore
     825    }
     826
     827    if ( ( 'pcloud_auth' === $do ) && ! empty( $auth_key ) ) {
     828
     829        if ( $locationid > 0 && $locationid < 100 ) {
     830            WP2pCloudFuncs::set_storred_val( PCLOUD_API_LOCATIONID, $locationid );
    813831            $result['status'] = 0;
    814832        }
    815833
    816         $auth_key = trim( sanitize_text_field( wp_unslash( $_GET['access_token'] ) ) );
    817 
    818         if ( ! empty( $auth_key ) ) {
    819             WP2pCloudFuncs::set_storred_val( PCLOUD_AUTH_KEY, $auth_key );
    820 
    821             print '<h2 style="color: green;text-align: center" class="wp2pcloud-login-succcess">You are successfully logged in!</h2>';
    822 
    823         }
    824     }
    825 
    826     $static_files_ver = '1.0.18';
     834        WP2pCloudFuncs::set_storred_val( PCLOUD_AUTH_KEY, $auth_key );
     835
     836        print '<h2 style="color: green;text-align: center" class="wp2pcloud-login-succcess">You are successfully logged in!</h2>';
     837
     838    }
     839
     840    $static_files_ver = '1.0.20';
    827841
    828842    wp_enqueue_script( 'wp2pcl-scr', plugins_url( '/assets/js/wp2pcl.js', __FILE__ ), array(), $static_files_ver, true );
     
    859873    WP2pCloudFuncs::get_storred_val( PCLOUD_AUTH_MAIL );
    860874    WP2pCloudFuncs::get_storred_val( PCLOUD_SCHDATA_KEY, 'daily' );
     875    WP2pCloudFuncs::get_storred_val( PCLOUD_SCHDATA_INCLUDE_MYSQL, '1' );
    861876    WP2pCloudFuncs::get_storred_val( PCLOUD_OPERATION );
    862877    WP2pCloudFuncs::get_storred_val( PCLOUD_HAS_ACTIVITY, '0' );
     
    887902    );
    888903
    889     wp_schedule_event( time(), '10_sec', 'init_autobackup', array(), true );
     904    wp_schedule_event( time(), '10_sec', 'init_autobackup', array( false ) );
    890905}
    891906
     
    902917    delete_option( PCLOUD_AUTH_MAIL );
    903918    delete_option( PCLOUD_SCHDATA_KEY );
     919    delete_option( PCLOUD_SCHDATA_INCLUDE_MYSQL );
    904920    delete_option( PCLOUD_OPERATION );
    905921    delete_option( PCLOUD_HAS_ACTIVITY );
     
    918934 *
    919935 * @return array
     936 * @noinspection PhpUnused
    920937 */
    921938function backup_to_pcloud_cron_schedules( $schedules ) {
     
    961978     */
    962979    function wp2pcl_load_scripts() {
    963         wp_register_script( 'wp2pcl-wp2pcljs', plugins_url( '/assets/js/wp2pcl.js', __FILE__ ), array(), '1.0.2', true );
     980        wp_register_script( 'wp2pcl-wp2pcljs', plugins_url( '/assets/js/wp2pcl.js', __FILE__ ), array(), '1.0.3', true );
    964981        wp_enqueue_script( 'jquery' );
    965982    }
  • pcloud-wp-backup/trunk/readme.txt

    r2732482 r2781798  
    1 ===  pCloud WP Backup ===
    2 Contributors: pCloud
     1=== pCloud WP Backup ===
     2Contributors: ploudapp, the_root
    33Tags: backup, pCloud
    44Requires at least: 5.0
    5 Tested up to: 6.0.0
    6 Stable tag: 1.0.2
     5Tested up to: 6.0.2
     6Requires PHP: 5.6
     7Stable tag: 1.0.3
    78License: GPLv3 or later
    89
     10The pCloud WP Backup plugin will help you to backup everything on your blog with one click and store it in the cloud in the most secure way.
     11
    912== Description ==
    10 pCloud WP Backup has been created to make instant backups of your blog and its data, regularly. Just choose a day, time and how often you wish your backup to be saved in your pCloud! You have a lot of content on your blog such as images, videos, and comments. If your database is erased or corrupted you may lose all the information you have generated over the years. By backing up your blog, you will be able to restore everything quickly and efficiently if anything happens. Having a current backup of your WordPress blog is critical for protecting your website, so back up your files and database backups into the cloud and restore with a single click! Just create pCloud account and never worry about it again! https://www.youtube.com/watch?v=s_rDLeqr-oA&t=1s&ab_channel=pCloud
     13# pCloud WP Backup
    1114
    12 == Screenshots ==
    13 1. Here's a screenshot of it in action
     15The pCloud WP Backup plugin was created to help you backup everything on your blog with just one click and store it in the cloud in the most secure way possible.
     16
     17Just create an account select a backup schedule, and we will take care of the rest.
     18
     19* The backup is done directly in the cloud, so you will have access to all your files on:
     20Our Blog admin interface.
     21* All your other devices (laptops, smartphones, tablets etc.) or via https://www.pcloud.com
     22
     23## Why you should always have a backup of your website and all its assets
     24
     25Backups are the ultimate insurance for your website. They ensure that if something were to happen, and you lost all data on it including backup files (which should be regularly updated), then at least one copy of everything would still exist so an emergency situation can easily be resolved with little downtime or disruption.
     26
     27Just set and forget with pCloud WP Backup. The plugin will backup all your important files automatically, so you can focus on what really matters!
     28
     29## Restoring backups
     30The plugin can not only create backups but if something goes wrong with your website it can restore a previous version in just one click
     31
     32## Security
     33To guarantee your file's safety, pCloud WP Backup uses TLS/SSL encryption, applied when information is transferred from your website to the pCloud servers. At pCloud data security is our top priority, and we do our best to apply first class safety measures. With pCloud, your files are stored on at least three server locations in a highly secure data storage area. Optionally, you can subscribe for pCloud Crypto and have your most important files encrypted and password protected. We provide the so called client-side encryption, which, unlike server-side encryption, means that no one, except you will, have the keys for file decryption.
     34
    1435
    1536== Installation ==
    16 Once installed, the authorization is 'one step' process.
    17 When you first access the plugin’s options page, it will ask you to authorize the plugin with pCloud. Login with your email and password and press the button.
     37Once installed, you will see a new menu \"pCloud Backup\", open the menu and use the \"Authenticate with pCloud\" link to authenticate with your pCloud account.
     38After successful authentication, you will be able to enjoy the full functionality of the plugin.
    1839
    1940= Minimum Requirements =
    2041
    21 1. PHP 5.6 or higher with [ZIP support](https://www.php.net/manual/en/zip.installation.php)
    22 2. [pCloud account](https://my.pcloud.com/#page=register&ref=1235)
     42* PHP 5.6 or higher with [ZIP support](https://www.php.net/manual/en/zip.installation.php)
     43* [pCloud account](https://my.pcloud.com/#page=register&ref=1235)
     44
     45
     46== Frequently Asked Questions ==
     47= I am having issues with the plugin, it does not work as expected, what to do ? =
     48
     49Click \"Backup Now\" and on the upper / right corner of the page you will see small \"debug\" button, click on it and the black info window will show much more debugging / useful info related to the backup process. You can send the content of that black window to: support@pcloud.com and ask for support from the pCloud team.
     50
     51= Why the manual ( Backup Now ) works, but the automatic / scheduled does not ? =
     52
     53If the manual backup mode works it means that the plugin is functioning correctly, on the other hand - to work correctly in automatic ( scheduled ) mode the website needs to have enough visitors, so they can kick-up the backup process or at least someone needs to visit the admin page of the blog.
     54
     55
     56== Screenshots ==
     571. Here is a screenshot of the plugin in action
     58
     59== Changelog ==
     60= 1.0.3 =
     61* Added an option to choose whether to include a database snapshot in the backup archive or not.
     62* Much more debugging is added in order to determine the Zipping process issues.
     63
     64= 1.0.2 =
     65* First public release, tested and confirmed to be stable enough.
     66
     67= 1.0.0 =
     68* Initial version of the plugin.
     69
     70
     71== Upgrade Notice ==
     72Plugin is more stable now and expected to work faster for bigger archives.
  • pcloud-wp-backup/trunk/views/wp2pcl-config.php

    r2732482 r2781798  
    1010$auth_mail = WP2pCloudFuncs::get_storred_val( PCLOUD_AUTH_MAIL );
    1111
    12 $lastbackupdt_tm = intval( WP2pCloudFuncs::get_storred_val( PCLOUD_LAST_BACKUPDT ) );
    13 
    14 $last_backup_data = ( $lastbackupdt_tm > 9999 ) ? gmdate( 'd.m.Y H:i:s', $lastbackupdt_tm ) :
    15     '<em class="pcl_transl" data-i10nk="no_bk_so_far">no auto backups so far</em>';
     12$php_extensions            = get_loaded_extensions();
     13$has_archive_ext_installed = array_search( 'zip', $php_extensions, true );
     14
     15$lastbackupdt_tm  = intval( WP2pCloudFuncs::get_storred_val( PCLOUD_LAST_BACKUPDT ) );
     16$last_backup_data = ( $lastbackupdt_tm > 9999 ) ? gmdate( 'd.m.Y H:i:s', $lastbackupdt_tm ) : '';
    1617
    1718if ( PCLOUD_DEBUG ) {
    1819    $freg = array(
     20        't'       => 'Test',
    1921        '1_hour'  => '1 Hour',
    2022        '4_hours' => '4 Hours',
     
    3436$sched = WP2pCloudFuncs::get_storred_val( PCLOUD_SCHDATA_KEY );
    3537
     38$wp2pcl_withmysql_chk = 'checked="checked"';
     39$wp2pcl_withmysql     = WP2pCloudFuncs::get_storred_val( PCLOUD_SCHDATA_INCLUDE_MYSQL );
     40if ( empty( $wp2pcl_withmysql ) || intval( $wp2pcl_withmysql ) < 1 ) {
     41    $wp2pcl_withmysql_chk = '';
     42}
     43
    3644$next_sch = wp_next_scheduled( 'wp2pcl_run_pcloud_backup_hook' );
    3745
     
    6674    $msg = sanitize_text_field( wp_unslash( $_GET['msg'] ) );
    6775}
     76
     77$auth_url = '#';
    6878
    6979if ( empty( $auth ) ) {
     
    8191
    8292    <div id="wp2pcloud-error" class="error notice" style="display: none"><p></p></div>
     93
     94    <?php if ( ! $has_archive_ext_installed ) : ?>
     95        <div id="wp2pcloud-error" class="error notice">
     96            <p class="pcl_transl" data-i10nk="no_zip_zlib_ext_found">
     97                No "zip" PHP extension has been found, backup will not be possible.
     98                Please, contact the support of your hosting company and request the extension to be enabled for your website.
     99            </p>
     100        </div>
     101    <?php endif; ?>
    83102
    84103    <?php if ( 'restore_ok' === $msg ) : ?>
     
    161180
    162181            <div class="wp2pcloud-register-wrap">
     182                <?php if ( $has_archive_ext_installed ) : ?>
    163183                <button type="button" id="run_wp_backup_now" class="button pcl_transl" data-i10nk="cta_backup_now">Make
    164184                    backup now
    165185                </button>
     186                <?php endif; ?>
     187            </div>
     188
     189            <div class="wp2pcloud-register-wrap" style="padding-bottom: 30px">
     190                <h4 class="pcl_transl" data-i10nk="incl_db_backup_ttl">Database backup:</h4>
     191
     192                <form action="" id="wp2_incl_db_form" autocomplete="off">
     193
     194                    <div id="setting-error-mysql-settings_updated" class="updated settings-error below-h2">
     195                        <p class="pcl_transl" data-i10nk="your_sett_saved">Your settings are saved</p>
     196                    </div>
     197
     198                    <div id="" class="below-h2">
     199                        <label for="wp2pcl_withmysql" data-i10nk="incl_db_backup_lbl">
     200                            Include Database ( MySQL ) in the backup:
     201                        </label>
     202                        <input type="checkbox" name="wp2pcl_withmysql" id="wp2pcl_withmysql" value="1"
     203                                    <?php echo esc_attr( $wp2pcl_withmysql_chk ); ?> />
     204                    </div>
     205
     206                    <input type="hidden" name="wp2pcl_nonce" value="<?php echo esc_attr( $nonce ); ?>"/>
     207
     208                </form>
     209
    166210            </div>
    167211
     
    197241
    198242                    <div style="display: flex; align-items: center; padding-top: 10px;">
    199                         <label for="freq" class="pcl_transl" data-i10nk="last_auto_backup">Last auto
    200                             backup:&nbsp;&nbsp;</label> <?php echo esc_html( $last_backup_data ); ?>
    201                     </div>
    202 
    203                     <input type="hidden" name="wp2pcl_nonce" id="wp2pcl_nonce" value="<?php echo esc_attr( $nonce ); ?>"/>
     243                        <label for="freq" class="pcl_transl" data-i10nk="last_auto_backup">Last auto backup:&nbsp;&nbsp;</label>
     244                        <?php if ( empty( $last_backup_data ) ) : ?>
     245                            <em class="pcl_transl" data-i10nk="no_bk_so_far">no auto backups so far</em>
     246                        <?php else : ?>
     247                            <?php echo esc_html( $last_backup_data ); ?>
     248                        <?php endif; ?>
     249                    </div>
     250
     251                    <input type="hidden" name="wp2pcl_nonce" value="<?php echo esc_attr( $nonce ); ?>"/>
    204252
    205253                </form>
Note: See TracChangeset for help on using the changeset viewer.