File: /home/h340499/public_html/wp-content/plugins/duplicator-pro/src/Package/Create/BuildComponents.php
<?php
/**
*
* @package Duplicator
* @copyright (c) 2022, Snap Creek LLC
*/
namespace Duplicator\Package\Create;
use Duplicator\Utils\Logging\DupLog;
use Duplicator\Addons\ProBase\License\License;
use Duplicator\Installer\Package\PComponents;
use Duplicator\Libs\Snap\SnapString;
use Duplicator\Libs\Snap\SnapWP;
use Duplicator\Libs\WpUtils\WpArchiveUtils;
use Exception;
class BuildComponents extends PComponents
{
const COMP_ACTION_ALL = 'all';
const COMP_ACTION_DB = 'database';
const COMP_ACTION_MEDIA = 'media';
const COMP_ACTION_CUSTOM = 'custom';
const COMPONENTS_ACTIONS = [
self::COMP_ACTION_ALL,
self::COMP_ACTION_DB,
self::COMP_ACTION_MEDIA,
self::COMP_ACTION_CUSTOM,
];
const COMPONENTS_PLUS_ACTIONS = [
self::COMP_ACTION_MEDIA,
self::COMP_ACTION_CUSTOM,
];
/** @var string[] */
protected $components = [];
/** @var array{dirs:string[],files:string[]} */
protected $filters = [
'dirs' => [],
'files' => [],
];
/**
* Class contructor
*
* @param string[] $components The components to build
*/
public function __construct($components)
{
$this->components = (array) $components;
if (in_array(self::COMP_PLUGINS_ACTIVE, $this->components)) {
$this->components = array_diff($this->components, [self::COMP_PLUGINS]);
}
if (in_array(self::COMP_THEMES_ACTIVE, $this->components)) {
$this->components = array_diff($this->components, [self::COMP_THEMES]);
}
$this->components = array_values($this->components);
DupLog::infoTrace("Components: " . implode(', ', $this->components));
$this->generateFilters();
}
/**
* Generate filter listh paths
*
* @return void
*/
public function generateFilters(): void
{
$this->filters = [
'dirs' => [],
'files' => [],
];
if (!in_array(self::COMP_CORE, $this->components)) {
$filters = $this->getCoreComponentPaths();
$this->filters['dirs'] = array_merge($this->filters['dirs'], $filters['dirs']);
$this->filters['files'] = array_merge($this->filters['files'], $filters['files']);
}
if (!in_array(self::COMP_DB, $this->components)) {
$filters = $this->getDBComponentPaths();
$this->filters['dirs'] = array_merge($this->filters['dirs'], $filters['dirs']);
$this->filters['files'] = array_merge($this->filters['files'], $filters['files']);
}
if (in_array(self::COMP_PLUGINS_ACTIVE, $this->components)) {
$filters = $this->getInactivePluginsComponentPaths();
$this->filters['dirs'] = array_merge($this->filters['dirs'], $filters['dirs']);
$this->filters['files'] = array_merge($this->filters['files'], $filters['files']);
} elseif (!in_array(self::COMP_PLUGINS, $this->components)) {
$filters = $this->getPluginsComponentPaths();
$this->filters['dirs'] = array_merge($this->filters['dirs'], $filters['dirs']);
$this->filters['files'] = array_merge($this->filters['files'], $filters['files']);
}
if (in_array(self::COMP_THEMES_ACTIVE, $this->components)) {
$filters = $this->getInactiveThemesComponentPaths();
$this->filters['dirs'] = array_merge($this->filters['dirs'], $filters['dirs']);
$this->filters['files'] = array_merge($this->filters['files'], $filters['files']);
} elseif (!in_array(self::COMP_THEMES, $this->components)) {
$filters = $this->getThemesComponentPaths();
$this->filters['dirs'] = array_merge($this->filters['dirs'], $filters['dirs']);
$this->filters['files'] = array_merge($this->filters['files'], $filters['files']);
}
if (!in_array(self::COMP_UPLOADS, $this->components)) {
$filters = $this->getMediaComponentPaths();
$this->filters['dirs'] = array_merge($this->filters['dirs'], $filters['dirs']);
$this->filters['files'] = array_merge($this->filters['files'], $filters['files']);
}
if (!in_array(self::COMP_OTHER, $this->components)) {
$filters = $this->getOtherComponentPaths();
$this->filters['dirs'] = array_merge($this->filters['dirs'], $filters['dirs']);
$this->filters['files'] = array_merge($this->filters['files'], $filters['files']);
}
$this->filters['dirs'] = array_unique($this->filters['dirs']);
$this->filters['files'] = array_unique($this->filters['files']);
}
/**
* Returns a list of files path to filter
*
* @return string[]
*/
public function getFiltersFiles()
{
return $this->filters['files'];
}
/**
* Returns a list of dirs path to filter
*
* @return string[]
*/
public function getFiltersDirs()
{
return $this->filters['dirs'];
}
/**
* Returns core directories and files of the WP install
*
* @return array{dirs: string[], files: string[]}
*/
private function getCoreComponentPaths(): array
{
$paths = [
'dirs' => [],
'files' => [],
];
$absRootPaths = SnapWP::getWpCoreFilesListInFolder();
$paths['dirs'] = array_map(fn($item): string => WpArchiveUtils::getArchiveListPaths('abs') . '/' . $item, $absRootPaths['dirs']);
$paths['files'] = array_map(fn($item): string => WpArchiveUtils::getArchiveListPaths('abs') . '/' . $item, $absRootPaths['files']);
foreach (SnapWP::getWPContentCoreDirs() as $dir) {
$paths['dirs'][] = WpArchiveUtils::getArchiveListPaths('wpcontent') . '/' . $dir;
}
return $paths;
}
/**
* Returns database directories and files of the WP install
*
* @return array{dirs: string[], files: string[]}
*/
private function getDBComponentPaths(): array
{
return [
'dirs' => [],
'files' => [],
];
}
/**
* Returns directories and file list of the Plugin component which includes all non-core files and folders
* in the wp-content folder and the plugins and mu-plugins folders which can be outside of wp-content
*
* @return array{dirs: string[], files: string[]}
*/
private function getPluginsComponentPaths(): array
{
$paths = [
'dirs' => [
WpArchiveUtils::getArchiveListPaths('plugins'),
WpArchiveUtils::getArchiveListPaths('muplugins'),
],
'files' => [],
];
$excludePaths = [
WpArchiveUtils::getArchiveListPaths('themes'),
WpArchiveUtils::getArchiveListPaths('uploads'),
];
$wpContentPath = WpArchiveUtils::getArchiveListPaths('wpcontent');
foreach (scandir($wpContentPath) as $basename) {
$tmpPath = $wpContentPath . '/' . $basename;
if (
$basename === '.'
|| $basename === '..'
|| in_array($tmpPath, $excludePaths)
|| in_array($basename, SnapWP::getWPContentCoreDirs())
) {
continue;
}
if (is_dir($tmpPath)) {
$paths['dirs'][] = $tmpPath;
} else {
$paths['files'][] = $tmpPath;
}
}
return $paths;
}
/**
* Directory and file list path of inactive plugins
*
* @return array{dirs: string[], files: string[]}
*/
private function getInactivePluginsComponentPaths(): array
{
$paths = [
'dirs' => [],
'files' => [],
];
foreach (SnapWP::getPluginsInfo(SnapWP::PLUGIN_INFO_INACTIVE) as $slug => $info) {
if (SnapString::contains($slug, '/')) {
$paths['dirs'][] = WpArchiveUtils::getArchiveListPaths('plugins') . '/' . dirname($slug);
} else {
$paths['files'][] = WpArchiveUtils::getArchiveListPaths('plugins') . '/' . $slug;
}
}
DupLog::traceObject("Inactive plugins:", $paths);
return $paths;
}
/**
* Directory and file list path of themes
*
* @return array{dirs: string[], files: string[]}
*/
private function getThemesComponentPaths(): array
{
return [
'dirs' => [WpArchiveUtils::getArchiveListPaths('themes')],
'files' => [],
];
}
/**
* Directory and file list path of inactive themes
*
* @return array{dirs: string[], files: string[]}
*/
private function getInactiveThemesComponentPaths(): array
{
$inactiveThemes = [
'dirs' => [],
'files' => [],
];
foreach (SnapWP::getThemesInfo() as $info) {
if ($info['isActive'] === true || (is_array($info['isActive']) && !empty($info['isActive']))) {
continue;
}
$inactiveThemes['dirs'][] = WpArchiveUtils::getArchiveListPaths('themes') . '/' . $info['slug'];
}
return $inactiveThemes;
}
/**
* Returns the paths related to the media Backup component
*
* @return array{dirs: string[], files: string[]}
*/
private function getMediaComponentPaths(): array
{
return [
'dirs' => [WpArchiveUtils::getArchiveListPaths('uploads')],
'files' => [],
];
}
/**
* Returns file and directory and file path lists of the "Other" package component
*
* @return array{dirs: string[], files: string[]}
*/
private function getOtherComponentPaths(): array
{
$paths = [
'dirs' => [],
'files' => [],
];
$absPath = WpArchiveUtils::getArchiveListPaths('abs');
$corePaths = SnapWP::getWpCoreFilesListInFolder();
foreach (scandir($absPath) as $basename) {
$tmpPath = $absPath . '/' . $basename;
if (
$basename === '.'
|| $basename === '..'
|| in_array($basename, $corePaths['dirs'])
|| in_array($basename, $corePaths['files'])
|| $tmpPath === WpArchiveUtils::getArchiveListPaths('wpcontent')
) {
continue;
}
if (is_dir($tmpPath)) {
$paths['dirs'][] = $tmpPath;
} else {
$paths['files'][] = $tmpPath;
}
}
return $paths;
}
/**
* Get label by compoentent
*
* @param string $component The component
*
* @return string
*/
public static function getLabel($component): string
{
switch ($component) {
case self::COMP_DB:
return __('Database', 'duplicator-pro');
case self::COMP_CORE:
return __('Core', 'duplicator-pro');
case self::COMP_PLUGINS:
return __('Plugins', 'duplicator-pro');
case self::COMP_PLUGINS_ACTIVE:
return __('Only Active Plugins', 'duplicator-pro');
case self::COMP_THEMES:
return __('Themes', 'duplicator-pro');
case self::COMP_THEMES_ACTIVE:
return __('Only Active Themes', 'duplicator-pro');
case self::COMP_UPLOADS:
return __('Media', 'duplicator-pro');
case self::COMP_OTHER:
return __('Other', 'duplicator-pro');
default:
throw new Exception('Invalid component: ' . $component);
}
}
/**
* Get label by compoentent action
*
* @param string $componentAction The component action
* @param bool $icon If true, the label will include an icon
*
* @return string
*/
public static function getActionLabel($componentAction, $icon = false): string
{
$result = '';
if ($icon) {
switch ($componentAction) {
case self::COMP_ACTION_ALL:
$result .= '<i class="fa-solid fa-square-check"></i>';
break;
case self::COMP_ACTION_DB:
$result .= '<i class="fa-solid fa-database"></i>';
break;
case self::COMP_ACTION_MEDIA:
$result .= '<i class="fa-solid fa-images"></i>';
break;
case self::COMP_ACTION_CUSTOM:
$result .= '<i class="fa-solid fa-gear"></i>';
break;
default:
throw new Exception('Invalid component action' . $componentAction);
}
$result .= ' ';
}
switch ($componentAction) {
case self::COMP_ACTION_ALL:
$result .= __('Full Site', 'duplicator-pro');
break;
case self::COMP_ACTION_DB:
$result .= __('Database Only', 'duplicator-pro');
break;
case self::COMP_ACTION_MEDIA:
$result .= __('Media Only', 'duplicator-pro');
break;
case self::COMP_ACTION_CUSTOM:
$result .= __('Custom', 'duplicator-pro');
break;
default:
throw new Exception('Invalid component action' . $componentAction);
}
return $result;
}
/**
* Get label by compoentent action
*
* @param string[] $components The active components
*
* @return string Enum of the component action (COMP_ACTION_*)
*/
public static function getActionFromComponents($components): string
{
if (count($components) === 1) {
switch ($components[0]) {
case self::COMP_DB:
return self::COMP_ACTION_DB;
case self::COMP_UPLOADS:
return self::COMP_ACTION_MEDIA;
default:
return self::COMP_ACTION_CUSTOM;
}
} elseif (array_diff(self::COMPONENTS_DEFAULT, $components) === []) {
return self::COMP_ACTION_ALL;
}
return self::COMP_ACTION_CUSTOM;
}
/**
* Returns the Backup components from the input array
*
* @param string[] $input the input array $_POST, $_GET, etc.
*
* @return string[]
*/
public static function getFromInput($input): array
{
$components = [];
foreach (self::COMPONENTS as $component) {
if (isset($input[$component])) {
$components[] = $component;
}
}
if (License::can(License::CAPABILITY_PACKAGE_COMPONENTS_PLUS)) {
return $components;
}
if ($components === self::COMPONENTS_DEFAULT || (count($components) === 1 && $components[0] === self::COMP_DB)) {
return $components;
}
return self::COMPONENTS_DEFAULT;
}
}