File: /var/www/html/delstar/wp-content/plugins/worker/src/MWP/Action/IncrementalBackup/ListFiles.php
<?php
/*
* This file is part of the ManageWP Worker plugin.
*
* (c) ManageWP LLC <contact@managewp.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class MWP_Action_IncrementalBackup_ListFiles extends MWP_Action_IncrementalBackup_AbstractFiles
{
/** @var Symfony_Filesystem_Filesystem */
protected $fileSystem;
public function __construct()
{
parent::__construct();
$this->fileSystem = new Symfony_Filesystem_Filesystem();
}
/**
* Return a list of all files
*
* @param array $params
* @param MWP_Worker_Request $request
*
* @return array
*/
public function queryFiles(array $params = array(), MWP_Worker_Request $request)
{
if (isset($params['query']) && is_array($params['query'])) {
$files = $this->getFilesInfo($params['query']);
} else {
try {
$files = $this->listFiles(ABSPATH, true);
} catch (UnexpectedValueException $e) {
$files = $this->listFilesWindowsPermissionsFix(ABSPATH, true);
}
}
return $this->createResult(array('files' => $files));
}
/**
* @param array $params
* @param MWP_Worker_Request $request
*
* @return array
*/
public function listDirectories(array $params = array(), MWP_Worker_Request $request)
{
$directories = $params['directories'];
$result = array();
foreach ($directories as $directory) {
$relativePath = $directory['path'];
$decodedPath = $directory['pathEncoded'] ? $this->pathDecode($relativePath) : $relativePath;
$recursive = isset($directory['recursive']) ? $directory['recursive'] : false;
$offset = isset($directory['offset']) ? $directory['offset'] : 0;
$limit = isset($directory['limit']) ? $directory['limit'] : 0;
$realPath = $this->getRealPath($decodedPath, true);
if (!file_exists($realPath)) {
$result[$relativePath] = false;
continue;
}
try {
$filesInDirectory = $this->listFiles($realPath, $recursive, $offset, $limit);
} catch (UnexpectedValueException $e) {
if ($relativePath !== ".") {
throw $e;
}
$filesInDirectory = $this->listFilesWindowsPermissionsFix($realPath, $recursive, $offset, $limit);
}
$result[$relativePath] = $filesInDirectory;
}
return $this->createResult(array('directories' => $result));
}
/**
* Return a list of files in the WordPress root directory, recursively
*
* @param string $rootPath
* @param bool $recursive
* @param int $offset
* @param int $limit
*
* @return array
*/
private function listFiles($rootPath, $recursive = false, $offset = 0, $limit = 0)
{
$result = array();
$iterator = $this->createIterator($recursive, $rootPath);
$i = 0;
foreach ($iterator as $file) {
if ($i++ < $offset) {
continue;
}
if ($limit !== 0 && $i > $offset + $limit) {
break;
}
/** @var SplFileInfo $file */
$fileResult = $this->createFileResult($file);
$result[] = $fileResult;
}
return $result;
}
/**
* This is a special case of listFiles function, with the purpose of bypassing the
* Windows permissions issue when the php user does not have permission to list
* the parent directory of "."
*
* See https://bugs.php.net/bug.php?id=43817 for the details of the issue.
*
* @param string $rootPath
* @param bool $recursive
* @param int $offset
* @param int $limit
*
* @return array
*/
private function listFilesWindowsPermissionsFix($rootPath, $recursive = false, $offset = 0, $limit = 0)
{
$result = array();
$iterator = $this->createIterator($recursive, $rootPath . DIRECTORY_SEPARATOR . 'wp-admin' . DIRECTORY_SEPARATOR . '..');
$i = 0;
foreach ($iterator as $file) {
if ($i++ < $offset) {
continue;
}
if ($limit !== 0 && $i > $offset + $limit) {
break;
}
/** @var SplFileInfo $file */
$fileResult = $this->createFileResult($file);
$fileResult['path'] = str_replace("wp-admin/../", "", $fileResult['path']);
$result[] = $fileResult;
}
return $result;
}
/**
* Get a list of file stats for given $files
*
* @param array $files
*
* @return array
*/
protected function getFilesInfo(array $files)
{
$result = array();
foreach ($files as $file) {
$relativePath = $file['path'];
$decodedPath = $file['pathEncoded'] ? $this->pathDecode($relativePath) : $relativePath;
$realPath = $this->getRealPath($decodedPath, true);
if (!file_exists($realPath)) {
$result[] = array(
'path' => $relativePath,
'exists' => false,
);
continue;
}
$file = new SplFileInfo($realPath);
$result[] = $this->createFileResult($file);
}
return $result;
}
/**
* @param string $realPath
* @param string $rootPath
*
* @return string
*/
private function getRelativePath($realPath, $rootPath)
{
$path = $this->fileSystem->makePathRelative($realPath, $rootPath);
return rtrim($path, '/\\');
}
/**
* @param SplFileInfo $file
*
* @return array
*/
private function createFileResult(SplFileInfo $file)
{
$fileResult = array(
'path' => $this->replaceWindowsPath($this->getRelativePath($file->getPathname(), $this->cleanPath(ABSPATH))),
'pathEncoded' => false,
'isLink' => false,
'exists' => false,
'isDirectory' => false,
'owner' => 0,
'group' => 0,
'permissions' => 0,
);
if (!seems_utf8($fileResult['path'])) {
$fileResult['path'] = $this->pathEncode($fileResult['path']);
$fileResult['pathEncoded'] = true;
}
try {
$fileResult['isLink'] = $file->isLink(); // need to be first
$fileResult['size'] = $file->getSize();
$fileResult['isDirectory'] = $file->isDir();
$fileResult['owner'] = $file->getOwner();
$fileResult['group'] = $file->getGroup();
$fileResult['permissions'] = $file->getPerms();
$fileResult['mTime'] = $file->getMTime();
$fileResult['exists'] = true;
if ($file->isLink()) {
$fileResult['linkTarget'] = $file->getLinkTarget();
};
} catch (RuntimeException $e) {
}
return $fileResult;
}
/**
* Create a recursive or non-recursive iterator for $path. Handles php 5.2 incompatibility.
*
* @param bool $recursive
* @param string $path
*
* @return Iterator
*/
private function createIterator($recursive, $path)
{
if ($recursive) {
// PHP 5.2.x does not have the SKIP_DOTS flag because it skips all dots by default
// The behavior was changed in PHP 5.3+ and it does not skip dots without the SKIP_DOTS flag
$php52 = version_compare(phpversion(), '5.3', '<');
if ($php52) {
$directory = new RecursiveDirectoryIterator($path);
} else {
/** @handled constant */
$directory = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS);
}
$iterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD);
} else {
$directory = new Symfony_Filesystem_FilesystemIterator($path, Symfony_Filesystem_FilesystemIterator::SKIP_DOTS);
$iterator = new IteratorIterator($directory);
}
return $iterator;
}
private function cleanPath($path) {
return preg_replace('#/{2,}#', '/', $path);
}
}