<?php
/**
* Class description
*
* @package package_name
* @author Cherry Team
* @license GPL-2.0+
*/
// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
die;
}
if ( ! class_exists( 'Jet_Theme_Core_Backups' ) ) {
/**
* Define Jet_Theme_Core_Backups class
*/
class Jet_Theme_Core_Backups {
/**
* Path to backup file
* @var string
*/
public $path;
/**
* Theme files to backup
* @var array
*/
public $files = array();
/**
* Messages holder
* @var string
*/
public $message = null;
/**
* A reference to an instance of this class.
*
* @since 1.0.0
* @var object
*/
private static $instance = null;
/**
* Constructor for the class
*/
public function __construct() {
// connect filesystem
$this->fs_connect();
// set path
$upload_dir = wp_upload_dir();
$upload_base_dir = $upload_dir['basedir'];
$this->path = trailingslashit( $upload_base_dir ) . 'kava-backups';
}
/**
* Try to create backup archive
*
* @since 1.0.0
* @return bool
*/
public function make_backup( $theme, $version ) {
global $wp_filesystem;
if ( ! current_user_can( 'manage_options' ) ) {
return false;
}
include_once( ABSPATH . '/wp-admin/includes/class-pclzip.php' );
if ( ! $this->check_path() ) {
return false;
}
$this->protect_path();
ini_set( 'max_execution_time', -1 );
set_time_limit( 0 );
$zip_name = $this->path . '/' . $theme . '-' . $version . '.zip';
$files = $this->get_files( $theme );
$files = implode( ',', $files );
$remove_path = $wp_filesystem->wp_themes_dir();
$zip = new PclZip( $zip_name );
$result = $zip->create( $files, PCLZIP_OPT_REMOVE_PATH, $remove_path );
if ( ! $result ) {
return false;
}
return str_replace( ABSPATH, home_url( '/' ), $zip_name );
}
/**
* Get backup files list
*
* @since 1.0.0
* @return array
*/
public function get_files( $theme ) {
global $wp_filesystem;
$path = $wp_filesystem->wp_themes_dir() . $theme;
$this->parse_dir( $path );
return $this->files;
}
/**
* Recursive function, that parse passed directory and add found files into 'file' property.
*
* @since 1.0.0
* @param string $dir path to directory to search files in.
* @return void|bool false
*/
public function parse_dir( $dir ) {
global $wp_filesystem;
$files = $wp_filesystem->dirlist( $dir );
if ( ! is_array( $files ) ) {
return false;
}
foreach ( $wp_filesystem->dirlist( $dir ) as $name => $data ) {
$current_path = trailingslashit( $dir ) . $name;
if ( 'd' == $data['type'] ) {
$this->parse_dir( $current_path );
continue;
}
$this->files[] = $current_path;
}
}
/**
* Check if backup directory exists and create it if not
*
* @since 1.0.0
* @return bool
*/
public function check_path() {
global $wp_filesystem;
$path = $this->prepare_path( $this->path );
if ( $wp_filesystem->exists( $path ) ) {
return true;
}
return $wp_filesystem->mkdir( $path );
}
/**
* Create .htaccess file in updates backup dir to protect it from direct access
*
* @since 1.0.0
* @return void|bool
*/
public function protect_path() {
global $wp_filesystem;
$path = $this->prepare_path( $this->path );
$file = $path . '/.htaccess';
if ( $wp_filesystem->exists( $file ) ) {
return true;
}
$wp_filesystem->put_contents( $file, 'deny from all' );
}
/**
* Prepeare path for using with filesystem API
*
* @since 1.0.0
* @param string $path path to prepare.
* @return string
*/
public function prepare_path( $path ) {
global $wp_filesystem;
return str_replace( ABSPATH, $wp_filesystem->abspath(), $path );
}
/**
* Get avaliable backups list
*
* @since 1.0.0
* @return array
*/
public function get_backups() {
global $wp_filesystem;
$path = $this->prepare_path( $this->path );
$files = $wp_filesystem->dirlist( $path );
$result = array();
if ( ! is_array( $files ) ) {
return $result;
}
if ( isset( $files['.htaccess'] ) ) {
unset( $files['.htaccess'] );
}
foreach ( $files as $file => $data ) {
if ( 'zip' !== pathinfo( $file, PATHINFO_EXTENSION ) ) {
continue;
}
$result[] = array(
'name' => $file,
'date' => date( 'M d Y, H:i', $data['lastmodunix'] ),
);
}
usort( $result, array( $this, 'date_compare' ) );
return $result;
}
/**
* Compare backups by date
*
* @since 1.0.0
* @param array $a 1st value.
* @param array $b 2nd value.
* @return bool
*/
public function date_compare( $a, $b ) {
$t1 = strtotime( $a['date'] );
$t2 = strtotime( $b['date'] );
return $t2 - $t1;
}
/**
* Download backup by filename
*
* @since 1.0.0
* @param string $file backup filename.
* @return void|bool false
*/
public function download_backup( $file ) {
if ( ! current_user_can( 'manage_options' ) ) {
$this->message = __( 'Permission denied', 'jet-theme-core' );
return false;
}
global $wp_filesystem;
$path = $this->prepare_path( $this->path );
$filepath = $path . '/' . $file;
if ( ! $wp_filesystem->exists( $filepath ) ) {
$this->message = __( 'File not exists', 'jet-theme-core' );
return false;
}
session_write_close();
header( 'Pragma: public' );
header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );
header( 'Cache-Control: public' );
header( 'Content-Description: File Transfer' );
header( 'Content-type: application/octet-stream' );
header( 'Content-Disposition: attachment; filename="' . $file . '"' );
header( 'Content-Transfer-Encoding: binary' );
header( 'Content-Length: ' . @filesize( $filepath ) );
$this->readfile_chunked( $filepath ) or header( 'Location: ' . $filepath );
exit();
}
/**
* Delete existing backup by filename
*
* @since 1.0.0
* @param string $file backup filename.
* @return bool
*/
public function delete_backup( $file ) {
if ( ! current_user_can( 'manage_options' ) ) {
$this->message = __( 'Permission denied', 'jet-theme-core' );
return false;
}
global $wp_filesystem;
$path = $this->prepare_path( $this->path );
$filepath = $path . '/' . $file;
if ( ! $wp_filesystem->exists( $filepath ) ) {
$this->message = __( 'File not exists', 'jet-theme-core' );
return false;
}
$delete = $wp_filesystem->delete( $filepath );
if ( false === $delete ) {
$this->message = __( 'Can\'t delete selected backup', 'jet-theme-core' );
}
return $delete;
}
/**
* Chunked file reading
*
* @since 1.0.0
* @param string $file fileptah.
* @param boolean $retbytes return bytes number or not.
* @return bool|int
*/
public function readfile_chunked( $file, $retbytes = true ) {
$chunksize = 1024 * 1024;
$buffer = '';
$cnt = 0;
$handle = @fopen( $file, 'r' );
if ( $size = @filesize( $file ) ) {
header( 'Content-Length: ' . $size );
}
if ( false === $handle ) {
Loading ...