File: //proc/self/cwd/wp-content/plugins/siteground-migrator/core/Directory_Service/Directory_Service.php
<?php
namespace SiteGround_Migrator\Directory_Service;
use SiteGround_Migrator\Helper\Log_Service_Trait;
use SiteGround_Migrator\Helper\Helper;
/**
* The directory service class.
*/
class Directory_Service {
use Log_Service_Trait;
/**
* List of child directories that should be created in temp dir.
*
* @since 1.0.0
*
* @var array
*/
private $child_directories = array(
'/plugins',
'/themes',
'/sql',
);
/**
* {@link Siteground_Migrator_Directory_Service} singleton instance.
*
* @since 1.0.0
* @access private
* @var \Siteground_Migrator_Directory_Service $instance {@link Siteground_Migrator_Directory_Service} singleton instance.
*/
private static $instance;
/**
* The constructor
*
* @since 1.0.0
*/
public function __construct() {
self::$instance = $this;
}
/**
* Get {@link Siteground_Migrator_Directory_Service} singleton instance.
*
* @since 1.0.0
*
* @return Siteground_Migrator_Directory_Service {@link Siteground_Migrator_Directory_Service} singleton instance.
*/
public static function get_instance() {
if ( null == self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Create the directory where the mysql tables will be dumped.
*
* @since 1.0.0
*
* @return bool True on success or if the directory already exists
* False on failure.
*/
public function create_temp_directories() {
// Get the temp directory.
$directory = $this->get_temp_directory_path();
// try to create the temp directory.
$result = $this->create_directory( $directory );
// Bail if the main temp directory was not created.
if ( false === $result ) {
return;
}
// Create child directories if the main directory was successfully created.
foreach ( $this->child_directories as $child_dir ) {
$this->create_directory( $directory . $child_dir );
}
}
/**
* Create directory.
*
* @since 1.0.0
*
* @param string $directory The new directory path.
*
* @return bool True is the directory is created.
* False on failure.
*/
public function create_directory( $directory ) {
if ( empty( $directory ) ) {
return $this->log_error( 'Temporary directory name is not set.' );
}
// The directory already exists.
if ( is_dir( $directory ) ) {
return true;
}
// Create the directory and return the result.
$is_directory_created = wp_mkdir_p( $directory );
// Bail if cannot create temp dir.
if ( false === $is_directory_created ) {
// translators: `$directory` is the name of directory that should be created.
$this->log_error( sprintf( 'Cannot create directory: %s.', $directory ) );
}
return $is_directory_created;
}
/**
* Empty temp dir after the transfer is completed.
*
* @since 1.0.0
*
* @param string $directory The directory to remove. Plugin temp dir by default.
*/
public function remove_temp_dir_content( $directory = '' ) {
global $wp_filesystem;
// Initialize the WP filesystem, no more using 'file-put-contents' function.
if ( empty( $wp_filesystem ) ) {
require_once( ABSPATH . '/wp-admin/includes/file.php' );
\WP_Filesystem();
}
if ( empty( $directory ) ) {
$directory = self::get_temp_directory_path();
}
// Bail if the temp dir doesn't exists.
if ( ! is_dir( self::get_temp_directory_path() ) ) {
return;
}
foreach ( scandir( $directory ) as $file ) {
// Skip system files.
if ( '.' === $file || '..' === $file ) {
continue;
}
// Remove the file and continue.
if ( ! is_dir( "$directory/$file" ) ) {
$wp_filesystem->delete( "$directory/$file" );
continue;
}
// Continue with child directories.
$this->remove_temp_dir_content( "$directory/$file" );
}
return true;
}
/**
* Remove temp dir upon deactivation.
*
* @since 1.0.0
*/
public function remove_temp_dir() {
global $wp_filesystem;
// Initialize the WP filesystem, no more using 'file-put-contents' function.
if ( empty( $wp_filesystem ) ) {
require_once( ABSPATH . '/wp-admin/includes/file.php' );
\WP_Filesystem();
}
// Remove the temporary dir and all it's content.
$wp_filesystem->rmdir( self::get_temp_directory_path(), true );
}
/**
* Return the total size of a directory in bytes.
*
* @since 1.0.0
*
* @param string $directory The directory which size to calculate.
*
* @return int $size The total size of the directory.
*/
public static function get_directory_size( $directory ) {
// Init the size.
$size = 0;
// Bail if the directory doesn't exists.
if ( ! file_exists( $directory ) ) {
// translators: `$directory` placeholder contains the name of directory which size we are trying to retrieve.
( new self )->log_error( sprintf( 'Directory: %s doesn\'t exists', $directory ) );
return;
}
// Init the iterator.
// We create this variable for code readability.
// Otherwise the foreach below looks very ugly.
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator(
$directory,
\FilesystemIterator::SKIP_DOTS
)
);
// Loop through all sub-directories and files
// and calculate the size of the directory.
foreach ( $iterator as $object ) {
// Increase the `size` by adding the current object size.
$size += $object->getSize();
}
// Finally return the total size of the directory.
return $size;
}
/**
* Get WordPress installation size.
*
* @since 1.0.0
*
* @return int $size The size of the installation.
*/
public static function get_wordpress_size() {
$size = 0;
$paths = array(
ABSPATH . 'wp-admin',
WP_CONTENT_DIR,
ABSPATH . 'wp-includes',
);
foreach ( $paths as $path ) {
$size += self::get_directory_size( $path );
}
// return the size.
return $size;
}
/**
* Creates a tree-structured array of directories and files from a given root folder.
*
* @param string $directory The directory.
*
* @since 1.0.0
*
* @return array Tree array.
*/
public function get_upload_paths( $directory ) {
// Init the dir and file arrays.
$paths = '';
// Make the dir innstance of `RecursiveDirectoryIterator`.
$directory = new \RecursiveDirectoryIterator(
(string) $directory,
\RecursiveDirectoryIterator::SKIP_DOTS
);
// Loop throug all directories and build the tree.
foreach ( $directory as $node ) {
// Skip PHP files.
if ( $node->isFile() && strtolower( $node->getExtension() ) === 'php' ) {
continue;
}
// Call the method recursivelly if the node is directory.
if ( $node->isDir() ) {
$paths .= $this->get_upload_paths( $node->getPathname() );
} else {
// We need to replace the ABSPATH with `/` and windows server backslashes.
$path = str_replace(
array(
ABSPATH,
'\\',
),
array(
'/',
'/',
),
$node->getPath()
);
$paths .= $path . '/' . $node->getFilename() . "\n";
}
}
// Return the paths.
return $paths;
}
/**
* Retrieve directories in certain folder.
*
* @since 1.0.0
*
* @param string $directory The main directory.
*
* @return array $directories Child directories in main dir.
*/
private function get_child_directories( $directory ) {
$directories = array();
// Make the directory innstance of `RecursiveDirectoryIterator`.
$directory_iterator = new \RecursiveDirectoryIterator(
WP_CONTENT_DIR . (string) $directory,
\RecursiveDirectoryIterator::SKIP_DOTS
);
// Loop through all directories and get the child directories.
foreach ( $directory_iterator as $node ) {
// Bail if the current node is not directory.
if (
! $node->isDir() ||
'siteground-migrator' === $node->getFilename()
) {
continue;
}
$directories[] = $directory . '/' . $node->getFilename();
}
// Return the directories.
return $directories;
}
/**
* Build array of all directories that should be archived.
*
* @since 1.0.0
*
* @return array $directories Directories that should be archived.
*/
public function get_plugin_and_theme_child_directories() {
$directories = array();
// The parent directories.
$parent_dirs = array(
'/plugins',
'/themes',
);
// Loop throught all parent directories
// and retrieve the sub directories in them.
foreach ( $parent_dirs as $directory ) {
$directories = array_merge( $directories, $this->get_child_directories( $directory ) );
}
// Finally return the directories that should be archived.
return $directories;
}
/**
* Retrieve temp directory name.
*
* @since 1.0.0
*
* @return string|bool False if the directory is not set, directory name otherwise.
*/
public static function get_temp_directory_path() {
// Get directory name.
$directory_name = get_option( 'siteground_migrator_temp_directory' );
// Bail if the directory name is empty.
if ( empty( $directory_name ) ) {
return false;
}
$upload_dir = wp_upload_dir();
$tmp_dir_name = Helper::is_flyweel() ? WP_CONTENT_DIR . '/uploads/' . $directory_name : $upload_dir['basedir'] . '/' . $directory_name;
// Return the full path to directory.
return $tmp_dir_name;
}
/**
* Check if temp directories have been created.
*
* @since 1.0.1
*
* @return bool True is directories exist, false otherwise.
*/
public function check_if_temp_dirs_extist() {
// Get the main temp dir.
$directory = $this->get_temp_directory_path();
// Bail if main directory is not created.
if ( ! is_dir( $directory ) ) {
return false;
}
// Loop through all child dirs and make sure each one has been created.
foreach ( $this->child_directories as $child_dir ) {
if ( ! is_dir( $directory . $child_dir ) ) {
return false;
}
}
// All dirs have been created.
return true;
}
}