PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backups, Restore, Migration & Clone / 4.11.0
WP STAGING – WordPress Backups, Restore, Migration & Clone v4.11.0
4.11.0 4.10.0 4.9.5 4.9.4 4.9.3 4.9.2 4.9.1 4.9.0 4.8.1 trunk 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.10.0 3.2.0 3.3.1 3.3.2 3.3.3 3.4.1 3.4.3 3.5.0 3.6.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 4.0.0 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.8.0
wp-staging / Staging / Ajax / DirectoryChildren.php
wp-staging / Staging / Ajax Last commit date
Create 1 day ago Delete 1 day ago Reset 1 day ago Update 1 day ago AbstractAjaxPrepare.php 1 day ago Create.php 1 day ago Delete.php 1 day ago DirectoryChildren.php 1 day ago Listing.php 1 day ago Repair.php 1 day ago Reset.php 1 day ago Setup.php 1 day ago SizeCalculator.php 1 day ago StagingSiteDataChecker.php 1 day ago Update.php 1 day ago
DirectoryChildren.php
127 lines
1 <?php
2
3 namespace WPStaging\Staging\Ajax;
4
5 use InvalidArgumentException;
6 use Throwable;
7 use WPStaging\Framework\Adapter\Directory;
8 use WPStaging\Framework\Component\AbstractTemplateComponent;
9 use WPStaging\Framework\Facades\Sanitize;
10 use WPStaging\Framework\Filesystem\PathIdentifier;
11 use WPStaging\Framework\TemplateEngine\TemplateEngine;
12 use WPStaging\Staging\Service\AbstractStagingSetup;
13 use WPStaging\Staging\Service\DirectoryScanner;
14 use WPStaging\Staging\Sites;
15
16
17
18
19 class DirectoryChildren extends AbstractTemplateComponent
20 {
21
22 private $stagingSetup;
23
24
25 private $directoryScanner;
26
27
28 private $directory;
29
30
31 private $stagingSites;
32
33 public function __construct(
34 TemplateEngine $templateEngine,
35 AbstractStagingSetup $stagingSetup,
36 DirectoryScanner $directoryScanner,
37 Directory $directory,
38 Sites $stagingSites
39 ) {
40 parent::__construct($templateEngine);
41 $this->stagingSetup = $stagingSetup;
42 $this->directoryScanner = $directoryScanner;
43 $this->directory = $directory;
44 $this->stagingSites = $stagingSites;
45 }
46
47
48
49
50 public function ajaxRender()
51 {
52 if (!$this->canRenderAjax()) {
53 return;
54 }
55
56 try {
57 $jobType = isset($_POST['jobType']) ? Sanitize::sanitizeString($_POST['jobType']) : AbstractStagingSetup::JOB_NEW_STAGING_SITE;
58 $cloneId = isset($_POST['cloneId']) ? Sanitize::sanitizeString($_POST['cloneId']) : '';
59 $dirPath = isset($_POST['dirPath']) ? Sanitize::sanitizePath($_POST['dirPath']) : '';
60 $prefix = isset($_POST['prefix']) ? Sanitize::sanitizeString($_POST['prefix']) : '';
61 $parentChecked = isset($_POST['isChecked']) && Sanitize::sanitizeBool($_POST['isChecked']);
62 $forceDefault = isset($_POST['forceDefault']) && Sanitize::sanitizeBool($_POST['forceDefault']);
63
64 $this->setupScanner($jobType, $cloneId);
65 $basePath = $this->getBasePath($prefix);
66 $path = $this->resolvePathWithinBase($dirPath, $basePath);
67
68 $directories = $this->directoryScanner->scanDirectory($path, $basePath, $prefix);
69 $listing = $this->directoryScanner->directoryListing($directories, $parentChecked, $forceDefault);
70
71 wp_send_json_success(['directoryListing' => $listing]);
72 } catch (Throwable $e) {
73 wp_send_json_error(['message' => $e->getMessage()]);
74 }
75 }
76
77 private function setupScanner(string $jobType, string $cloneId)
78 {
79 if ($jobType === AbstractStagingSetup::JOB_UPDATE || $jobType === AbstractStagingSetup::JOB_RESET) {
80 if ($cloneId === '') {
81 throw new InvalidArgumentException('Invalid clone ID provided.');
82 }
83
84 $stagingSiteDto = $this->stagingSites->getStagingSiteDtoByCloneId($cloneId);
85 if ($jobType === AbstractStagingSetup::JOB_RESET) {
86 $this->stagingSetup->initResetJob($stagingSiteDto);
87 } else {
88 $this->stagingSetup->initUpdateJob($stagingSiteDto);
89 }
90 } else {
91 $this->stagingSetup->initNewStagingSite();
92 }
93
94 $this->directoryScanner->setStagingSetup($this->stagingSetup);
95 }
96
97 private function getBasePath(string $prefix): string
98 {
99 if ($prefix === PathIdentifier::IDENTIFIER_ABSPATH) {
100 return trailingslashit(wp_normalize_path($this->directory->getAbsPath()));
101 }
102
103 if ($prefix === PathIdentifier::IDENTIFIER_WP_CONTENT) {
104 return trailingslashit(wp_normalize_path($this->directory->getWpContentDirectory()));
105 }
106
107 throw new InvalidArgumentException('Invalid directory path identifier.');
108 }
109
110 private function resolvePathWithinBase(string $dirPath, string $basePath): string
111 {
112 $resolvedBase = realpath($basePath);
113 $resolvedPath = realpath($basePath . ltrim($dirPath, '/\\'));
114 if ($resolvedBase === false || $resolvedPath === false) {
115 throw new InvalidArgumentException('Invalid directory path.');
116 }
117
118 $resolvedBase = wp_normalize_path($resolvedBase);
119 $resolvedPath = wp_normalize_path($resolvedPath);
120 if ($resolvedPath !== $resolvedBase && strpos(trailingslashit($resolvedPath), trailingslashit($resolvedBase)) !== 0) {
121 throw new InvalidArgumentException('Directory path is outside the allowed base path.');
122 }
123
124 return $resolvedPath;
125 }
126 }
127