PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.0-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.0-beta
16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / _inc / lib / admin-pages / class-jetpack-about-page.php
jetpack / _inc / lib / admin-pages Last commit date
class-akismet-admin-chrome.php 2 weeks ago class-jetpack-about-page.php 1 month ago class-jetpack-ai-page.php 1 month ago class-jetpack-redux-state-helper.php 2 weeks ago class.jetpack-admin-page.php 1 month ago class.jetpack-landing-page.php 2 years ago class.jetpack-react-page.php 6 months ago class.jetpack-settings-page.php 7 months ago
class-jetpack-about-page.php
606 lines
1 <?php
2 /**
3 * Class for the Jetpack About Page within the wp-admin.
4 *
5 * @package automattic/jetpack
6 */
7
8 /**
9 * Disable direct access and execution.
10 */
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit( 0 );
13 }
14
15 require_once __DIR__ . '/class.jetpack-admin-page.php';
16
17 /**
18 * Builds the landing page and its menu.
19 */
20 class Jetpack_About_Page extends Jetpack_Admin_Page {
21
22 /**
23 * Show the settings page only when Jetpack is connected or in dev mode.
24 *
25 * @var bool If the page should be shown.
26 */
27 protected $dont_show_if_not_active = true;
28
29 /**
30 * Anonymous info about a12s. The method fetch_a8c_data() stores the response from wpcom here.
31 *
32 * @var array
33 */
34 private $a8c_data = null;
35
36 /**
37 * Add a submenu item to the Jetpack admin menu.
38 *
39 * @return string
40 */
41 public function get_page_hook() {
42 // Add the main admin Jetpack menu.
43 return add_submenu_page(
44 '',
45 esc_html__( 'About Jetpack', 'jetpack' ),
46 '',
47 'jetpack_admin_page',
48 'jetpack_about',
49 array( $this, 'render' )
50 );
51 }
52
53 /**
54 * Add page action
55 *
56 * @param string $hook Hook of current page.
57 */
58 public function add_page_actions( $hook ) {
59 if ( 'admin_page_jetpack_about' === $hook ) {
60 $this->a8c_data = $this->fetch_a8c_data();
61 }
62 }
63
64 /**
65 * Enqueues scripts and styles for the admin page.
66 */
67 public function page_admin_scripts() {
68 wp_enqueue_style( 'plugin-install' );
69 wp_enqueue_script( 'plugin-install' );
70 // required for plugin modal action button functionality.
71 wp_enqueue_script( 'updates' );
72 // required for modal popup JS and styling.
73 wp_enqueue_style( 'thickbox' );
74 wp_enqueue_script( 'thickbox' );
75 }
76
77 /**
78 * Load styles for static page.
79 */
80 public function additional_styles() {
81 Jetpack_Admin_Page::load_wrapper_styles();
82 }
83
84 /**
85 * Render the page with a common top and bottom part, and page specific content
86 */
87 public function render() {
88 Jetpack_Admin_Page::wrap_ui( array( $this, 'page_render' ), array( 'show-nav' => false ) );
89 }
90
91 /**
92 * Render the page content
93 */
94 public function page_render() {
95 ?>
96 <div class="jp-lower">
97 <h1 class="screen-reader-text"><?php esc_html_e( 'About Jetpack', 'jetpack' ); ?></h1>
98 <div class="jetpack-about__main">
99 <div class="jetpack-about__logo">
100 <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 800 96" style="enable-background:new 0 0 800 96;" xml:space="preserve">
101 <g>
102 <path style="fill: #39c;" d="M292.922,78c-19.777,0-32.598-14.245-32.598-29.078V47.08c0-15.086,12.821-29.08,32.598-29.08
103 c19.861,0,32.682,13.994,32.682,29.08v1.843C325.604,63.755,312.783,78,292.922,78z M315.044,47.245
104 c0-10.808-7.877-20.447-22.122-20.447s-22.04,9.639-22.04,20.447v1.341c0,10.811,7.795,20.614,22.04,20.614
105 s22.122-9.803,22.122-20.614V47.245z"/>
106 <path d="M69.602,75.821l-7.374-13.826H29.463l-7.124,13.826H11.277l30.167-55.81h8.715l30.671,55.81H69.602z M45.552,30.906
107 L33.401,54.369h24.72L45.552,30.906z"/>
108 <path d="M128.427,78c-20.028,0-29.329-10.894-29.329-25.391V20.012h10.391v32.765c0,10.308,6.788,16.424,19.692,16.424
109 c13.242,0,18.687-6.116,18.687-16.424V20.012h10.475v32.598C158.342,66.436,149.46,78,128.427,78z"/>
110 <path d="M216.667,28.727v47.094h-10.475V28.727h-24.386v-8.715h59.245v8.715H216.667z"/>
111 <path d="M418.955,75.821V31.659l-2.766,4.861l-23.379,39.301h-5.112L364.569,36.52l-2.765-4.861v44.162h-10.224v-55.81h14.497
112 l22.038,38.296L390.713,63l2.599-4.692l21.786-38.296h14.331v55.81H418.955z"/>
113 <path d="M508.619,75.821l-7.374-13.826H468.48l-7.123,13.826h-11.061l30.167-55.81h8.715l30.669,55.81H508.619z M484.569,30.906
114 l-12.151,23.464h24.72L484.569,30.906z"/>
115 <path d="M562.081,28.727v47.094h-10.474V28.727h-24.386v-8.715h59.245v8.715H562.081z"/>
116 <path d="M638.924,28.727v47.094H628.45V28.727h-24.386v-8.715h59.245v8.715H638.924z"/>
117 <path d="M689.118,75.821v-50.53c4.19,0,5.866-2.263,5.866-5.28h4.442v55.81H689.118z"/>
118 <path d="M781.464,35.765c-5.028-4.609-12.402-8.967-22.374-8.967c-14.916,0-23.296,10.225-23.296,20.867v1.089
119 c0,10.558,8.464,20.445,24.05,20.445c9.303,0,17.012-4.441,21.872-8.965L788,66.854C781.883,72.887,771.492,78,759.174,78
120 c-21.118,0-33.939-13.743-33.939-28.828v-1.843c0-15.084,13.993-29.329,34.44-29.329c11.816,0,22.541,4.944,28.324,11.146
121 L781.464,35.765z"/>
122 <path d="M299.82,37.417c1.889,1.218,2.418,3.749,1.192,5.648l-9.553,14.797c-1.226,1.901-3.752,2.452-5.637,1.234l0,0
123 c-1.886-1.22-2.421-3.745-1.192-5.647l9.553-14.797C295.41,36.753,297.935,36.201,299.82,37.417L299.82,37.417z"/>
124 </g>
125 </svg>
126 </div>
127 <div class="jetpack-about__content">
128 <div class="jetpack-about__images">
129 <ul class="jetpack-about__gravatars">
130 <?php $this->display_gravatars(); ?>
131 </ul>
132 <p class="meet-the-team">
133 <a href="https://automattic.com/about/" target="_blank" rel="noopener noreferrer" class="jptracks" data-jptracks-name="jetpack_about_meet_the_team"><?php esc_html_e( 'Meet the Automattic team', 'jetpack' ); ?></a>
134 <svg class="gridicons-external" height="24" width="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g><path d="M19 13v6c0 1.105-.895 2-2 2H5c-1.105 0-2-.895-2-2V7c0-1.105.895-2 2-2h6v2H5v12h12v-6h2zM13 3v2h4.586l-7.793 7.793 1.414 1.414L19 6.414V11h2V3h-8z"></path></g></svg>
135 </p>
136 </div>
137
138 <div class="jetpack-about__text">
139 <p>
140 <?php esc_html_e( 'We are the people behind WordPress.com, WooCommerce, Jetpack, Simplenote, Longreads, VaultPress, Akismet, Gravatar, Crowdsignal, Cloudup, and more. We believe in making the web a better place.', 'jetpack' ); ?>
141 <a href="https://automattic.com/" target="_blank" rel="noopener noreferrer" class="jptracks" data-jptracks-name="jetpack_about_learn_more">
142 <?php esc_html_e( 'Learn more about us', 'jetpack' ); ?>
143 </a>
144 <svg class="gridicons-external" height="24" width="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g><path d="M19 13v6c0 1.105-.895 2-2 2H5c-1.105 0-2-.895-2-2V7c0-1.105.895-2 2-2h6v2H5v12h12v-6h2zM13 3v2h4.586l-7.793 7.793 1.414 1.414L19 6.414V11h2V3h-8z"></path></g></svg>
145 </p>
146 <p>
147 <?php
148 echo esc_html(
149 sprintf(
150 /* translators: first placeholder is the number of Automattic employees. The second is the number of countries of origin*/
151 __( 'We’re a distributed company with over %1$s Automatticians in more than %2$s countries speaking at least %3$s different languages. Our common goal is to democratize publishing so that anyone with a story can tell it, regardless of income, gender, politics, language, or where they live in the world.', 'jetpack' ),
152 $this->a8c_data['a12s'],
153 $this->a8c_data['countries'],
154 $this->a8c_data['languages']
155 )
156 );
157 ?>
158 </p>
159 <p>
160 <?php esc_html_e( 'We believe in Open Source and the vast majority of our work is available under the GPL.', 'jetpack' ); ?>
161 </p>
162 <p>
163 <?php
164 // Maybe use printf() because we'll want to escape the string but still allow for the link, so we can't use esc_html_e().
165 echo wp_kses(
166 __( 'We strive to live by the <a href="https://automattic.com/creed/" target="_blank" class="jptracks" data-jptracks-name="jetpack_about_creed" rel="noopener noreferrer">Automattic Creed</a><svg class="gridicons-external" height="24" width="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g><path d="M19 13v6c0 1.105-.895 2-2 2H5c-1.105 0-2-.895-2-2V7c0-1.105.895-2 2-2h6v2H5v12h12v-6h2zM13 3v2h4.586l-7.793 7.793 1.414 1.414L19 6.414V11h2V3h-8z"></path></g></svg>', 'jetpack' ),
167 array(
168 'a' => array(
169 'href' => array(),
170 'class' => array(),
171 'target' => array(),
172 'rel' => array(),
173 'data-jptracks-name' => array(),
174 ),
175 'svg' => array(
176 'class' => array(),
177 'height' => array(),
178 'width' => array(),
179 'xmlns' => array(),
180 'viewbox' => array(),
181 ),
182 'g' => array(),
183 'path' => array(
184 'd' => array(),
185 ),
186 )
187 );
188 ?>
189 </p>
190 <p>
191 <a href="https://automattic.com/work-with-us" target="_blank" rel="noopener noreferrer" class="jptracks" data-jptracks-name="jetpack_about_work_with_us"><?php esc_html_e( 'Come work with us', 'jetpack' ); ?>
192 </a><svg class="gridicons-external" height="24" width="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g><path d="M19 13v6c0 1.105-.895 2-2 2H5c-1.105 0-2-.895-2-2V7c0-1.105.895-2 2-2h6v2H5v12h12v-6h2zM13 3v2h4.586l-7.793 7.793 1.414 1.414L19 6.414V11h2V3h-8z"></path></g></svg>
193 </p>
194 </div>
195 </div>
196 </div>
197
198 <div class="jetpack-about__colophon">
199 <h3><?php esc_html_e( 'Popular WordPress services by Automattic', 'jetpack' ); ?></h3>
200 <ul class="jetpack-about__services">
201 <?php $this->display_plugins(); ?>
202 </ul>
203
204 <p class="jetpack-about__services-more">
205 <?php
206 echo wp_kses(
207 __( 'For even more of our WordPress plugins, please take a look at <a href="https://profiles.wordpress.org/automattic/#content-plugins" target="_blank" rel="noopener noreferrer" class="jptracks" data-jptracks-name="jetpack_about_wporg_profile">our WordPress.org profile</a>.', 'jetpack' ),
208 array(
209 'a' => array(
210 'href' => array(),
211 'target' => array(),
212 'rel' => array(),
213 'class' => array(),
214 'data-jptracks-name' => array(),
215 ),
216 )
217 );
218 ?>
219 </p>
220 </div>
221 </div>
222 <?php
223 }
224
225 /**
226 * Add information cards for a8c plugins.
227 */
228 public function display_plugins() {
229 $plugins_allowedtags = array(
230 'a' => array(
231 'href' => array(),
232 'title' => array(),
233 'target' => array(),
234 ),
235 'abbr' => array( 'title' => array() ),
236 'acronym' => array( 'title' => array() ),
237 'code' => array(),
238 'pre' => array(),
239 'em' => array(),
240 'strong' => array(),
241 'ul' => array(),
242 'ol' => array(),
243 'li' => array(),
244 'p' => array(),
245 'br' => array(),
246 );
247
248 // slugs for plugins we want to display.
249 $a8c_plugins = $this->a8c_data['featured_plugins'];
250
251 // need this to access the plugins_api() function.
252 include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
253
254 $plugins = array();
255 foreach ( $a8c_plugins as $slug ) {
256 $args = array(
257 'slug' => $slug,
258 'fields' => array(
259 'added' => false,
260 'author' => false,
261 'author_profile' => false,
262 'banners' => false,
263 'contributors' => false,
264 'donate_link' => false,
265 'homepage' => false,
266 'reviews' => false,
267 'screenshots' => false,
268 'support_threads' => false,
269 'support_threads_resolved' => false,
270 'sections' => false,
271 'tags' => false,
272 'versions' => false,
273
274 'compatibility' => true,
275 'downloaded' => true,
276 'downloadlink' => true,
277 'icons' => true,
278 'last_updated' => true,
279 'num_ratings' => true,
280 'rating' => true,
281 'requires' => true,
282 'requires_php' => true,
283 'short_description' => true,
284 'tested' => true,
285 ),
286 );
287
288 // should probably add some error checking here too.
289 $api = plugins_api( 'plugin_information', $args );
290 $plugins[] = $api;
291 }
292
293 foreach ( $plugins as $plugin ) {
294 if ( is_object( $plugin ) ) {
295 $plugin = (array) $plugin;
296 }
297
298 $title = wp_kses( $plugin['name'], $plugins_allowedtags );
299 $version = wp_kses( $plugin['version'], $plugins_allowedtags );
300
301 $name = wp_strip_all_tags( $title . ' ' . $version );
302
303 // Remove any HTML from the description.
304 $description = wp_strip_all_tags( $plugin['short_description'] );
305
306 $wp_version = get_bloginfo( 'version' );
307
308 $compatible_php = ( empty( $plugin['requires_php'] ) || version_compare( phpversion(), $plugin['requires_php'], '>=' ) );
309 $compatible_wp = ( empty( $plugin['requires'] ) || version_compare( $wp_version, $plugin['requires'], '>=' ) );
310
311 $action_links = array();
312
313 // install button.
314 if ( current_user_can( 'install_plugins' ) || current_user_can( 'update_plugins' ) ) {
315 $status = install_plugin_install_status( $plugin );
316 switch ( $status['status'] ) {
317 case 'install':
318 if ( $status['url'] ) {
319 if ( $compatible_php && $compatible_wp ) {
320 $action_links[] = sprintf(
321 '<a class="install-now button jptracks is-rna" data-slug="%1$s" href="%2$s" aria-label="%3$s" data-name="%4$s" data-jptracks-name="jetpack_about_install_button" data-jptracks-prop="%4$s">%5$s</a>',
322 esc_attr( $plugin['slug'] ),
323 esc_url( $status['url'] ),
324 /* translators: %s: plugin name and version */
325 esc_attr( sprintf( __( 'Install %s now', 'jetpack' ), $name ) ),
326 esc_attr( $name ),
327 esc_html__( 'Install Now', 'jetpack' )
328 );
329 } else {
330 $action_links[] = sprintf(
331 '<button type="button" class="button button-disabled" disabled="disabled">%s</button>',
332 _x( 'Cannot Install', 'plugin', 'jetpack' )
333 );
334 }
335 }
336 break;
337
338 case 'update_available':
339 if ( $status['url'] ) {
340 $action_links[] = sprintf(
341 '<a class="update-now button aria-button-if-js jptracks" data-plugin="%1$s" data-slug="%2$s" href="%3$s" aria-label="%4$s" data-name="%5$s" data-jptracks-name="jetpack_about_update_button" data-jptracks-prop="%5$s">%6$s</a>',
342 esc_attr( $status['file'] ),
343 esc_attr( $plugin['slug'] ),
344 esc_url( $status['url'] ),
345 /* translators: %s: plugin name and version */
346 esc_attr( sprintf( __( 'Update %s now', 'jetpack' ), $name ) ),
347 esc_attr( $name ),
348 __( 'Update Now', 'jetpack' )
349 );
350 }
351 break;
352
353 case 'latest_installed':
354 case 'newer_installed':
355 if ( is_plugin_active( $status['file'] ) ) {
356 $action_links[] = sprintf(
357 '<button type="button" class="button button-disabled" disabled="disabled">%s</button>',
358 _x( 'Active', 'plugin', 'jetpack' )
359 );
360 } elseif ( current_user_can( 'activate_plugin', $status['file'] ) ) {
361 $button_text = __( 'Activate', 'jetpack' );
362 /* translators: %s: plugin name */
363 $button_label = _x( 'Activate %s', 'plugin', 'jetpack' );
364 $activate_url = add_query_arg(
365 array(
366 '_wpnonce' => wp_create_nonce( 'activate-plugin_' . $status['file'] ),
367 'action' => 'activate',
368 'plugin' => $status['file'],
369 ),
370 network_admin_url( 'plugins.php' )
371 );
372
373 if ( is_network_admin() ) {
374 $button_text = __( 'Network Activate', 'jetpack' );
375 /* translators: %s: plugin name */
376 $button_label = _x( 'Network Activate %s', 'plugin', 'jetpack' );
377 $activate_url = add_query_arg( array( 'networkwide' => 1 ), $activate_url );
378 }
379
380 $action_links[] = sprintf(
381 '<a href="%1$s" class="button activate-now" aria-label="%2$s" data-jptracks-name="jetpack_about_activate_button" data-jptracks-prop="%3$s">%4$s</a>',
382 esc_url( $activate_url ),
383 esc_attr( sprintf( $button_label, $plugin['name'] ) ),
384 esc_attr( $plugin['name'] ),
385 $button_text
386 );
387 } else {
388 $action_links[] = sprintf(
389 '<button type="button" class="button button-disabled" disabled="disabled">%s</button>',
390 _x( 'Installed', 'plugin', 'jetpack' )
391 );
392 }
393 break;
394 }
395 }
396
397 $plugin_install = "plugin-install.php?tab=plugin-information&amp;plugin={$plugin['slug']}&amp;TB_iframe=true&amp;width=600&amp;height=550";
398 $details_link = is_multisite()
399 ? network_admin_url( $plugin_install )
400 : admin_url( $plugin_install );
401
402 if ( ! empty( $plugin['icons']['svg'] ) ) {
403 $plugin_icon_url = $plugin['icons']['svg'];
404 } elseif ( ! empty( $plugin['icons']['2x'] ) ) {
405 $plugin_icon_url = $plugin['icons']['2x'];
406 } elseif ( ! empty( $plugin['icons']['1x'] ) ) {
407 $plugin_icon_url = $plugin['icons']['1x'];
408 } else {
409 $plugin_icon_url = $plugin['icons']['default'];
410 }
411 ?>
412
413 <li class="jetpack-about__plugin plugin-card-<?php echo sanitize_html_class( $plugin['slug'] ); ?>">
414 <?php
415 if ( ! $compatible_php || ! $compatible_wp ) {
416 echo '<div class="notice inline notice-error notice-alt"><p>';
417 if ( ! $compatible_php && ! $compatible_wp ) {
418 esc_html_e( 'This plugin doesn&#8217;t work with your versions of WordPress and PHP.', 'jetpack' );
419 if ( current_user_can( 'update_core' ) && current_user_can( 'update_php' ) ) {
420 printf(
421 /* translators: 1: "Update WordPress" screen URL, 2: "Update PHP" page URL */
422 ' ' . wp_kses( __( '<a href="%1$s">Please update WordPress</a>, and then <a href="%2$s">learn more about updating PHP</a>.', 'jetpack' ), array( 'a' => array( 'href' => true ) ) ),
423 esc_url( self_admin_url( 'update-core.php' ) ),
424 esc_url( wp_get_update_php_url() )
425 );
426 wp_update_php_annotation();
427 } elseif ( current_user_can( 'update_core' ) ) {
428 printf(
429 /* translators: %s: "Update WordPress" screen URL */
430 ' ' . wp_kses( __( '<a href="%s">Please update WordPress</a>.', 'jetpack' ), array( 'a' => array( 'href' => true ) ) ),
431 esc_url( self_admin_url( 'update-core.php' ) )
432 );
433 } elseif ( current_user_can( 'update_php' ) ) {
434 printf(
435 /* translators: %s: "Update PHP" page URL */
436 ' ' . wp_kses( __( '<a href="%s">Learn more about updating PHP</a>.', 'jetpack' ), array( 'a' => array( 'href' => true ) ) ),
437 esc_url( wp_get_update_php_url() )
438 );
439 wp_update_php_annotation();
440 }
441 } elseif ( ! $compatible_wp ) {
442 esc_html_e( 'This plugin doesn&#8217;t work with your version of WordPress.', 'jetpack' );
443 if ( current_user_can( 'update_core' ) ) {
444 printf(
445 /* translators: %s: "Update WordPress" screen URL */
446 ' ' . wp_kses( __( '<a href="%s">Please update WordPress</a>.', 'jetpack' ), array( 'a' => array( 'href' => true ) ) ),
447 esc_url( self_admin_url( 'update-core.php' ) )
448 );
449 }
450 } elseif ( ! $compatible_php ) {
451 esc_html_e( 'This plugin doesn&#8217;t work with your version of PHP.', 'jetpack' );
452 if ( current_user_can( 'update_php' ) ) {
453 printf(
454 /* translators: %s: "Update PHP" page URL */
455 ' ' . wp_kses( __( '<a href="%s">Learn more about updating PHP</a>.', 'jetpack' ), array( 'a' => array( 'href' => true ) ) ),
456 esc_url( wp_get_update_php_url() )
457 );
458 wp_update_php_annotation();
459 }
460 }
461 echo '</p></div>';
462 }
463 ?>
464
465 <div class="plugin-card-top">
466 <div class="name column-name">
467 <h3>
468 <a href="<?php echo esc_url( $details_link ); ?>" class="jptracks thickbox open-plugin-details-modal" data-jptracks-name="jetpack_about_plugin_modal" data-jptracks-prop="<?php echo esc_attr( $plugin['slug'] ); ?>">
469 <?php echo esc_html( $title ); ?>
470 <img src="<?php echo esc_url( $plugin_icon_url ); ?>" class="plugin-icon" alt="<?php esc_attr_e( 'Plugin icon', 'jetpack' ); ?>" aria-hidden="true">
471 </a>
472 </h3>
473 </div>
474 <div class="desc column-description">
475 <p><?php echo esc_html( $description ); ?></p>
476 </div>
477
478 <div class="details-link">
479 <a class="jptracks thickbox open-plugin-details-modal" href="<?php echo esc_url( $details_link ); ?>" data-jptracks-name="jetpack_about_plugin_details_modal" data-jptracks-prop="<?php echo esc_attr( $plugin['slug'] ); ?>"><?php esc_html_e( 'More Details', 'jetpack' ); ?></a>
480 </div>
481 </div>
482
483 <div class="plugin-card-bottom">
484 <div class="meta">
485 <?php
486 wp_star_rating(
487 array(
488 'rating' => $plugin['rating'],
489 'type' => 'percent',
490 'number' => $plugin['num_ratings'],
491 )
492 );
493 ?>
494 <span class="num-ratings" aria-hidden="true">(<?php echo esc_html( number_format_i18n( $plugin['num_ratings'] ) ); ?> <?php esc_html_e( 'ratings', 'jetpack' ); ?>)</span>
495 <div class="downloaded">
496 <?php
497 if ( $plugin['active_installs'] >= 1000000 ) {
498 $active_installs_millions = floor( $plugin['active_installs'] / 1000000 );
499 $active_installs_text = sprintf(
500 /* translators: number of millions of installs. */
501 _nx( '%s+ Million', '%s+ Million', $active_installs_millions, 'Active plugin installations', 'jetpack' ),
502 number_format_i18n( $active_installs_millions )
503 );
504 } elseif ( 0 === $plugin['active_installs'] ) {
505 $active_installs_text = _x( 'Less Than 10', 'Active plugin installations', 'jetpack' );
506 } else {
507 $active_installs_text = number_format_i18n( $plugin['active_installs'] ) . '+';
508 }
509 /* translators: number of active installs */
510 printf( esc_html__( '%s Active Installations', 'jetpack' ), esc_html( $active_installs_text ) );
511 ?>
512 </div>
513 </div>
514
515 <div class="action-links">
516 <?php
517 if ( $action_links ) {
518 // The var simply collects strings that have already been sanitized.
519 // phpcs:ignore WordPress.Security.EscapeOutput
520 echo '<ul class="action-buttons"><li>' . implode( '</li><li>', $action_links ) . '</li></ul>';
521 }
522 ?>
523 </div>
524 </div>
525 </li>
526 <?php
527
528 }
529 }
530
531 /**
532 * Fetch anonymous data about A12s from wpcom: total count, number of countries, languages spoken.
533 *
534 * @since 7.4
535 *
536 * @return array $data
537 */
538 private function fetch_a8c_data() {
539 $data = get_transient( 'jetpack_a8c_data' );
540 if ( false === $data ) {
541 $data = json_decode(
542 wp_remote_retrieve_body(
543 wp_remote_get( 'https://public-api.wordpress.com/wpcom/v2/jetpack-about' )
544 ),
545 true
546 );
547 if ( ! empty( $data ) && is_array( $data ) ) {
548 set_transient( 'jetpack_a8c_data', $data, WEEK_IN_SECONDS );
549 } else {
550 // Fallback if everything fails.
551 $data = array(
552 'a12s' => 888,
553 'countries' => 69,
554 'languages' => 83,
555 'featured_plugins' => array(
556 'woocommerce',
557 'activitypub',
558 'wp-job-manager',
559 'wp-super-cache',
560 ),
561 );
562 }
563 }
564 return $data;
565 }
566
567 /**
568 * Compile and display a list of avatars for A12s that gave their permission.
569 *
570 * @since 7.3
571 */
572 public function display_gravatars() {
573 $hashes = array(
574 'https://1.gravatar.com/avatar/d2ab03dbab0c97740be75f290a2e3190',
575 'https://2.gravatar.com/avatar/b0b357b291ac72bc7da81b4d74430fe6',
576 'https://2.gravatar.com/avatar/9e149207a0e0818abed0edbb1fb2d0bf',
577 'https://2.gravatar.com/avatar/9f376366854d750124dffe057dda99c9',
578 'https://1.gravatar.com/avatar/1c75d26ad0d38624f02b15accc1f20cd',
579 'https://1.gravatar.com/avatar/c510e69d83c7d10be4df64feeff4e46a',
580 'https://0.gravatar.com/avatar/88ec0dcadea38adf5f30a17e54e9b248',
581 'https://1.gravatar.com/avatar/1ec3571e0201a990ceca5e365e780efa',
582 'https://0.gravatar.com/avatar/0619d4de8aef78c81b2194ff1d164d85',
583 'https://0.gravatar.com/avatar/7fdcad31a04def0ab9583af475c9036c',
584 'https://0.gravatar.com/avatar/b3618d70c63bbc5cc7caee0beded5ff0',
585 'https://1.gravatar.com/avatar/4d346581a3340e32cf93703c9ce46bd4',
586 'https://2.gravatar.com/avatar/9c2f6b95a00dfccfadc6a912a2b859ba',
587 'https://1.gravatar.com/avatar/1a33e7a69df4f675fcd799edca088ac2',
588 'https://2.gravatar.com/avatar/d5dc443845c134f365519568d5d80e62',
589 'https://0.gravatar.com/avatar/c0ccdd53794779bcc07fcae7b79c4d80',
590 );
591 $output = '';
592 foreach ( $hashes as $hash ) {
593 $output .= '<li><img src="' . esc_url( $hash ) . '?s=150"></li>' . "\n";
594 }
595 echo wp_kses(
596 $output,
597 array(
598 'li' => true,
599 'img' => array(
600 'src' => true,
601 ),
602 )
603 );
604 }
605 }
606