PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 3.8.2
WP STAGING – WordPress Backup, Restore, Migration & Clone v3.8.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 / Framework / SiteInfo.php
wp-staging / Framework Last commit date
Adapter 2 years ago Analytics 2 years ago Assets 2 years ago Auth 1 year ago BackgroundProcessing 2 years ago CloningProcess 2 years ago Collection 3 years ago Command 5 years ago Component 2 years ago DI 2 years ago Database 2 years ago DependencyResolver 2 years ago Exceptions 2 years ago Facades 2 years ago Filesystem 1 year ago Interfaces 5 years ago Mails 1 year ago Network 2 years ago Notices 2 years ago Permalinks 1 year ago Queue 2 years ago Rest 2 years ago Security 1 year ago Settings 1 year ago Staging 2 years ago TemplateEngine 5 years ago ThirdParty 2 years ago Traits 1 year ago Utils 2 years ago AnalyticsServiceProvider.php 2 years ago AssetServiceProvider.php 5 years ago CommonServiceProvider.php 1 year ago ErrorHandler.php 2 years ago NoticeServiceProvider.php 2 years ago SettingsServiceProvider.php 2 years ago SiteInfo.php 2 years ago Url.php 3 years ago
SiteInfo.php
285 lines
1 <?php
2
3 namespace WPStaging\Framework;
4
5 use WPStaging\Framework\Staging\CloneOptions;
6
7 /**
8 * Class SiteInfo
9 *
10 * Provides information about the current site.
11 *
12 * @package WPStaging\Site
13 */
14 class SiteInfo
15 {
16 /**
17 * The key used in DB to store is cloneable feature in clone options
18 * @var string
19 */
20 const IS_CLONEABLE_KEY = 'isCloneable';
21
22 /**
23 * The file which make staging site cloneable
24 * This way is depreciated
25 * @var string
26 */
27 const CLONEABLE_FILE = '.wp-staging-cloneable';
28
29 /**
30 * The key used in DB to store whether site is staging or not
31 * @var string
32 */
33 const IS_STAGING_KEY = 'wpstg_is_staging_site';
34
35 /**
36 * The file which makes a site a staging site
37 * @var string
38 */
39 const STAGING_FILE = '.wp-staging';
40
41 /** @var string */
42 const HOSTED_ON_WP = 'wp.com';
43
44 /** @var string */
45 const HOSTED_ON_FLYWHEEL = 'flywheel';
46
47 /** @var string */
48 const HOSTED_ON_BITNAMI = 'bitnami';
49
50 /** @var string */
51 const OTHER_HOST = 'other';
52
53 /**
54 * @var CloneOptions
55 */
56 private $cloneOptions;
57
58 /**
59 * @var array
60 */
61 private $errors = [];
62
63 public function __construct()
64 {
65 // TODO: inject using DI
66 $this->cloneOptions = new CloneOptions();
67 }
68
69 /**
70 * @return bool True if it is staging site. False otherwise.
71 */
72 public function isStagingSite(): bool
73 {
74 if (defined('WPSTAGING_DEV_SITE') && WPSTAGING_DEV_SITE === true) {
75 return true;
76 }
77
78 if (get_option(self::IS_STAGING_KEY) === "true") {
79 return true;
80 }
81
82 return file_exists(ABSPATH . self::STAGING_FILE);
83 }
84
85 /**
86 * @return bool True if it is staging site. False otherwise.
87 */
88 public function isCloneable(): bool
89 {
90 // Site should be cloneable if not staging i.e. production site
91 if (!$this->isStagingSite()) {
92 return true;
93 }
94
95 // Old condition to check if staging site is cloneable
96 if (file_exists(ABSPATH . self::CLONEABLE_FILE)) {
97 return true;
98 }
99
100 // New condition for checking whether staging is cloneable or not
101 return $this->cloneOptions->get(self::IS_CLONEABLE_KEY, false);
102 }
103
104 /**
105 * Check if WP is installed in subdirectory
106 * If siteurl and home are not identical we assume the site is located in a subdirectory
107 * related to that instruction https://wordpress.org/support/article/giving-wordpress-its-own-directory/
108 *
109 * @return bool
110 */
111 public function isInstalledInSubDir(): bool
112 {
113 $siteUrl = get_option('siteurl');
114 $homeUrl = get_option('home');
115
116 //Get URL path e.g.https://example.com/path will return /path
117 $siteUrlPath = wp_parse_url($siteUrl, PHP_URL_PATH);
118 $homeUrlPath = wp_parse_url($homeUrl, PHP_URL_PATH);
119
120 if ($siteUrlPath === null && $homeUrlPath === null || $siteUrlPath === $homeUrlPath) {
121 return false;
122 }
123
124 if ($siteUrlPath === null && $homeUrlPath !== null) {
125 return true;
126 }
127
128 return false;
129 }
130
131 /**
132 * Enable the cloning for current staging site.
133 *
134 * @return bool
135 */
136 public function enableStagingSiteCloning(): bool
137 {
138 // Early Bail: if site is not staging
139 if (!$this->isStagingSite()) {
140 return false;
141 }
142
143 // Early Bail: if cloning already enabled
144 if ($this->isCloneable()) {
145 return true;
146 }
147
148 return $this->cloneOptions->set(self::IS_CLONEABLE_KEY, true);
149 }
150
151 /**
152 * Enable the cloning for current staging site.
153 *
154 * @return bool
155 */
156 public function disableStagingSiteCloning(): bool
157 {
158 // Early Bail: if site is not staging
159 if (!$this->isStagingSite()) {
160 return false;
161 }
162
163 // Early Bail: if cloning already disabled
164 if (!$this->isCloneable()) {
165 return true;
166 }
167
168 // First try disabling if cloneable feature exist due to old way.
169 $cloneableFile = trailingslashit(ABSPATH) . self::CLONEABLE_FILE;
170 if (file_exists($cloneableFile) && !unlink($cloneableFile)) {
171 // Error if files exists but unable to unlink
172 return false;
173 }
174
175 // Staging site may have been made cloneable through both ways
176 // So now try disabling through new way
177 return (!file_exists($cloneableFile) && $this->cloneOptions->delete(self::IS_CLONEABLE_KEY));
178 }
179
180 /**
181 * @return bool True if "short_open_tags" is enabled, false if disabled.
182 */
183 public function isPhpShortTagsEnabled(): bool
184 {
185 return in_array(strtolower(ini_get('short_open_tags')), ['1', 'on', 'true']);
186 }
187
188 /**
189 * Is WP Bakery plugin active?
190 *
191 * @return bool
192 */
193 public function isWpBakeryActive(): bool
194 {
195 return defined('WPB_VC_VERSION');
196 }
197
198 /**
199 * Is Jetpack plugin active?
200 *
201 * @return bool
202 */
203 public function isJetpackActive(): bool
204 {
205 return class_exists('Jetpack');
206 }
207
208 /**
209 * @return string[]
210 */
211 public function getErrors(): array
212 {
213 return $this->errors;
214 }
215
216 /**
217 * @return bool
218 */
219 public function isBitnami(): bool
220 {
221 return ABSPATH === '/opt/bitnami/wordpress/';
222 }
223
224 /**
225 * @return bool
226 */
227 public function isWpContentOutsideAbspath(): bool
228 {
229 $wpContentDir = wp_normalize_path(WP_CONTENT_DIR);
230 $abspath = wp_normalize_path(ABSPATH);
231
232 return !(strpos($wpContentDir, $abspath) === 0);
233 }
234
235 /**
236 * @return bool
237 */
238 public function isFlywheel(): bool
239 {
240 if (!$this->isWpContentOutsideAbspath()) {
241 return false;
242 }
243
244 return file_exists(trailingslashit(wp_normalize_path(ABSPATH)) . '.fw-config.php');
245 }
246
247 /**
248 * @return bool
249 */
250 public function isHostedOnWordPressCom(): bool
251 {
252 if (!$this->isWpContentOutsideAbspath()) {
253 return false;
254 }
255
256 $parentDirectory = dirname(trailingslashit(wp_normalize_path(WP_CONTENT_DIR)));
257 $wpcomDetection = trailingslashit($parentDirectory) . '__wp__';
258 if (!is_link($wpcomDetection)) {
259 return false;
260 }
261
262 return true;
263 }
264
265 /**
266 * @return string
267 */
268 public function getHostingType(): string
269 {
270 if ($this->isFlywheel()) {
271 return self::HOSTED_ON_FLYWHEEL;
272 }
273
274 if ($this->isHostedOnWordPressCom()) {
275 return self::HOSTED_ON_WP;
276 }
277
278 if ($this->isBitnami()) {
279 return self::HOSTED_ON_BITNAMI;
280 }
281
282 return self::OTHER_HOST;
283 }
284 }
285