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