PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backups, Restore, Migration & Clone / trunk
WP STAGING – WordPress Backups, Restore, Migration & Clone vtrunk
4.11.1 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 week ago Delete 1 week ago Reset 1 week ago Update 1 week ago AbstractAjaxPrepare.php 1 week ago Create.php 1 week ago Delete.php 1 week ago DirectoryChildren.php 1 week ago Listing.php 1 week ago Repair.php 1 week ago Reset.php 1 week ago Setup.php 1 week ago SizeCalculator.php 1 week ago StagingSiteDataChecker.php 1 week ago Update.php 1 week 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