PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents / 4.6.5
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents v4.6.5
4.6.5 4.6.4 4.6.3 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 trunk 1.0.0 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 2.0.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.1.3 3.2.0 3.2.1 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9 4.0.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.14 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.0.9 4.1.0 4.1.1 4.1.10 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.3.0 4.3.1 4.4.0 4.4.1 4.4.10 4.4.11 4.4.2 4.4.3 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 4.5.0 4.5.1
embedpress / EmbedPress / Includes / Classes / SitePerformance.php
embedpress / EmbedPress / Includes / Classes Last commit date
Analytics 2 months ago Database 3 months ago DynamicFieldResolver.php 2 months ago Elementor_Enhancer.php 8 months ago EmbedPress_Core_Installer.php 6 years ago EmbedPress_Notice.php 5 months ago EmbedPress_Plugin_Usage_Tracker.php 2 months ago Extend_CustomPlayer_Controls.php 3 months ago Extend_Elementor_Controls.php 1 year ago FeatureNoticeManager.php 1 month ago FeatureNotices.php 1 month ago FeaturePreviewModal.php 1 month ago Feature_Enhancer.php 2 months ago GoogleReviewsAdminPage.php 1 month ago GoogleReviewsApify.php 1 month ago GoogleReviewsManaged.php 2 weeks ago GoogleReviewsRenderer.php 2 weeks ago GoogleReviewsRestController.php 2 weeks ago GoogleReviewsStore.php 1 month ago Helper.php 1 month ago Pdf_Thumbnail_Handler.php 1 month ago PermalinkHelper.php 1 year ago SitePerformance.php 5 days ago View_Count_Display.php 2 months ago
SitePerformance.php
239 lines
1 <?php
2
3 /**
4 * Site Performance — install and activate xSpeed Cache from the onboarding wizard.
5 *
6 * The toggle means "install and activate xSpeed". Whether page caching is then
7 * turned ON is not ours to decide: it depends on whether anything already owns
8 * the page cache on this site. That question is answered by the portable
9 * Detector in includes/Vendor/page-cache-safety/, copied from the xSpeed repo.
10 *
11 * @package EmbedPress
12 */
13
14 namespace EmbedPress\Includes\Classes;
15
16 defined('ABSPATH') || exit;
17
18 use WPDeveloper\PageCacheSafety\Detector;
19 use WPDeveloper\PageCacheSafety\Setup;
20
21 class SitePerformance
22 {
23 /**
24 * Records that EmbedPress is the one that installed xSpeed, so we can
25 * describe the outcome honestly on a later screen.
26 */
27 const INSTALLED_BY_US_OPTION = 'embedpress_site_performance_installed';
28
29 /**
30 * Load the vendored detector + setup pair.
31 *
32 * Both are guarded with class_exists() internally, so another WPDeveloper
33 * plugin carrying its own copy does not fatal — first one loaded wins.
34 */
35 private static function load()
36 {
37 $dir = EMBEDPRESS_PLUGIN_DIR_PATH . 'includes/Vendor/page-cache-safety/';
38
39 if (!class_exists('\WPDeveloper\PageCacheSafety\Detector')) {
40 require_once $dir . 'class-page-cache-safety.php';
41 }
42 if (!class_exists('\WPDeveloper\PageCacheSafety\Setup')) {
43 require_once $dir . 'class-page-cache-setup.php';
44 }
45 }
46
47 /**
48 * The state the onboarding card renders from.
49 *
50 * @return array{
51 * available:bool, installed:bool, active:bool,
52 * field_clear:bool, state:string, blocker:string
53 * }
54 */
55 public static function get_status()
56 {
57 self::load();
58
59 $installed = Setup::is_installed();
60 $active = Setup::is_active();
61 $supported = Setup::is_supported();
62
63 // is_field_clear() is true only when nothing owns the page cache AND
64 // nothing about the site's state was unreadable or ambiguous. "We could
65 // not tell" is not "the field is clear".
66 $field_clear = Detector::is_field_clear();
67 $verdict = Detector::classify();
68
69 $status = [
70 // Offer it only on a site that has never had xSpeed. A site that
71 // already has it has decided about it; re-offering is nagging.
72 'available' => $supported && !$installed && !Setup::has_settings(),
73 'installed' => $installed,
74 'active' => $active,
75 'supported' => $supported,
76 'field_clear' => $field_clear,
77 'state' => isset($verdict['state']) ? $verdict['state'] : '',
78 'blocker' => self::blocker_label($verdict),
79 ];
80
81 /**
82 * Filter the Site Performance offer status.
83 *
84 * @param array $status Offer availability and page-cache verdict.
85 */
86 return apply_filters('embedpress/site_performance_status', $status);
87 }
88
89 /**
90 * Name whoever already owns the page cache, for the card's explanation.
91 *
92 * The Detector deliberately returns codes rather than sentences — the
93 * wording is ours because the textdomain is ours.
94 */
95 private static function blocker_label($verdict)
96 {
97 if (empty($verdict['blockers']) || !is_array($verdict['blockers'])) {
98 return '';
99 }
100
101 foreach ($verdict['blockers'] as $blocker) {
102 if (!empty($blocker['label'])) {
103 return (string) $blocker['label'];
104 }
105 }
106
107 return '';
108 }
109
110 /**
111 * Install + activate xSpeed, enabling page caching only when the field is clear.
112 *
113 * @return array{success:bool, message:string, caching_enabled:bool}
114 */
115 public static function install()
116 {
117 self::load();
118
119 if (!current_user_can('install_plugins')) {
120 return self::fail(__('You do not have permission to install plugins.', 'embedpress'));
121 }
122
123 if (!Setup::is_supported()) {
124 return self::fail(__('This site does not meet the minimum requirements for xSpeed Cache.', 'embedpress'));
125 }
126
127 // Nothing owns the page cache => xSpeed may own it. Something does =>
128 // install it, but do not touch the page cache. Never fight for it.
129 $enable_cache = Detector::is_field_clear();
130
131 if (!Setup::is_installed()) {
132 $downloaded = self::download();
133
134 if (is_wp_error($downloaded)) {
135 return self::fail($downloaded->get_error_message());
136 }
137 }
138
139 /*
140 * prepare() writes the target state BEFORE activation, and that order is
141 * load-bearing. xSpeed's activation reads what is already stored rather
142 * than stamping over it, and configuring afterwards silently does
143 * nothing: Settings_Manager::update() resolves modules through a
144 * Module_Registry that is empty for a plugin activated part-way through
145 * the request.
146 *
147 * It runs on BOTH paths, including the occupied one. Skipping it does
148 * not mean "change nothing" -- it means xSpeed's own set_defaults()
149 * sees a fresh install and seeds its recommended profile, switching on
150 * gzip, browser caching and HTML/CSS minification. On the very site
151 * where we promised to touch nothing, the user would get markup
152 * rewriting they never agreed to, and no page cache either.
153 *
154 * Writing the settings option is what suppresses that first-run path.
155 */
156 $ours = Setup::prepare($enable_cache);
157
158 $activated = activate_plugin(Setup::PLUGIN_FILE);
159
160 if (is_wp_error($activated)) {
161 if ($ours) {
162 Setup::rollback();
163 }
164
165 return self::fail($activated->get_error_message());
166 }
167
168 /*
169 * Safe on both paths: finish() reads back what prepare() was told, so
170 * on an occupied site it clears the wizard redirect and the snapshot
171 * without enabling a cache we deliberately left off.
172 */
173 Setup::finish();
174
175 update_option(self::INSTALLED_BY_US_OPTION, true, false);
176
177 return [
178 'success' => true,
179 'caching_enabled' => $enable_cache,
180 'message' => $enable_cache
181 ? __('xSpeed Cache installed and page caching enabled.', 'embedpress')
182 : __('xSpeed Cache installed. Page caching was left off because another plugin already handles it on this site.', 'embedpress'),
183 ];
184 }
185
186 /**
187 * Download and unpack xSpeed from wordpress.org.
188 *
189 * Setup installs nothing by design — the host owns the install, its
190 * capability checks, and its UI.
191 *
192 * @return true|\WP_Error
193 */
194 private static function download()
195 {
196 require_once ABSPATH . 'wp-admin/includes/file.php';
197 require_once ABSPATH . 'wp-admin/includes/misc.php';
198 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
199 require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
200
201 $api = plugins_api('plugin_information', [
202 'slug' => Setup::PLUGIN_SLUG,
203 'fields' => ['sections' => false],
204 ]);
205
206 if (is_wp_error($api)) {
207 return $api;
208 }
209
210 $upgrader = new \Plugin_Upgrader(new \WP_Ajax_Upgrader_Skin());
211 $result = $upgrader->install($api->download_link);
212
213 if (is_wp_error($result)) {
214 return $result;
215 }
216
217 if (!$result) {
218 return new \WP_Error(
219 'embedpress_xspeed_install_failed',
220 __('Could not install xSpeed Cache.', 'embedpress')
221 );
222 }
223
224 return true;
225 }
226
227 /**
228 * @return array{success:bool, message:string, caching_enabled:bool}
229 */
230 private static function fail($message)
231 {
232 return [
233 'success' => false,
234 'caching_enabled' => false,
235 'message' => $message,
236 ];
237 }
238 }
239