summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/jetpack/modules/stats.php')
-rw-r--r--plugins/jetpack/modules/stats.php891
1 files changed, 434 insertions, 457 deletions
diff --git a/plugins/jetpack/modules/stats.php b/plugins/jetpack/modules/stats.php
index 362793b8..cb28c431 100644
--- a/plugins/jetpack/modules/stats.php
+++ b/plugins/jetpack/modules/stats.php
@@ -11,18 +11,22 @@
* Feature: Engagement
* Additional Search Queries: statistics, tracking, analytics, views, traffic, stats
*
- * @package Jetpack
+ * @package automattic/jetpack
*/
-use Automattic\Jetpack\Tracking;
use Automattic\Jetpack\Connection\Client;
+use Automattic\Jetpack\Connection\Manager as Connection_Manager;
+use Automattic\Jetpack\Connection\XMLRPC_Async_Call;
+use Automattic\Jetpack\Redirect;
+use Automattic\Jetpack\Status;
+use Automattic\Jetpack\Tracking;
if ( defined( 'STATS_VERSION' ) ) {
return;
}
define( 'STATS_VERSION', '9' );
-defined( 'STATS_DASHBOARD_SERVER' ) or define( 'STATS_DASHBOARD_SERVER', 'dashboard.wordpress.com' );
+defined( 'STATS_DASHBOARD_SERVER' ) || define( 'STATS_DASHBOARD_SERVER', 'dashboard.wordpress.com' );
add_action( 'jetpack_modules_loaded', 'stats_load' );
@@ -41,29 +45,28 @@ function stats_load() {
add_action( 'wp_head', 'stats_admin_bar_head', 100 );
add_action( 'wp_head', 'stats_hide_smile_css' );
+ add_action( 'embed_head', 'stats_hide_smile_css' );
add_action( 'jetpack_admin_menu', 'stats_admin_menu' );
// Map stats caps.
add_filter( 'map_meta_cap', 'stats_map_meta_caps', 10, 3 );
- if ( isset( $_GET['oldwidget'] ) ) {
- // Old one.
- add_action( 'wp_dashboard_setup', 'stats_register_dashboard_widget' );
- } else {
- add_action( 'admin_init', 'stats_merged_widget_admin_init' );
- }
+ add_action( 'admin_init', 'stats_merged_widget_admin_init' );
- add_filter( 'jetpack_xmlrpc_methods', 'stats_xmlrpc_methods' );
+ add_filter( 'jetpack_xmlrpc_unauthenticated_methods', 'stats_xmlrpc_methods' );
add_filter( 'pre_option_db_version', 'stats_ignore_db_version' );
- // Add an icon to see stats in WordPress.com for a particular post
+ // Add an icon to see stats in WordPress.com for a particular post.
add_action( 'admin_print_styles-edit.php', 'jetpack_stats_load_admin_css' );
add_filter( 'manage_posts_columns', 'jetpack_stats_post_table' );
add_filter( 'manage_pages_columns', 'jetpack_stats_post_table' );
add_action( 'manage_posts_custom_column', 'jetpack_stats_post_table_cell', 10, 2 );
add_action( 'manage_pages_custom_column', 'jetpack_stats_post_table_cell', 10, 2 );
+
+ require_once __DIR__ . '/stats/class-jetpack-stats-upgrade-nudges.php';
+ add_action( 'updating_jetpack_version', array( 'Jetpack_Stats_Upgrade_Nudges', 'unset_nudges_setting' ) );
}
/**
@@ -75,7 +78,6 @@ function stats_load() {
function stats_merged_widget_admin_init() {
if ( current_user_can( 'view_stats' ) ) {
add_action( 'load-index.php', 'stats_enqueue_dashboard_head' );
- add_action( 'wp_dashboard_setup', 'stats_register_widget_control_callback' ); // Hacky but works.
add_action( 'jetpack_dashboard_widget', 'stats_jetpack_dashboard_widget' );
}
}
@@ -109,7 +111,7 @@ function jetpack_is_dnt_enabled() {
}
foreach ( $_SERVER as $name => $value ) {
- if ( 'http_dnt' == strtolower( $name ) && 1 == $value ) {
+ if ( 'http_dnt' === strtolower( $name ) && 1 === (int) $value ) {
return true;
}
}
@@ -128,8 +130,8 @@ function jetpack_is_dnt_enabled() {
function stats_ignore_db_version( $version ) {
if (
is_admin() &&
- isset( $_GET['page'] ) && 'stats' === $_GET['page'] &&
- isset( $_GET['chart'] ) && strpos($_GET['chart'], 'admin-bar-hours') === 0
+ isset( $_GET['page'] ) && 'stats' === $_GET['page'] && // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ isset( $_GET['chart'] ) && strpos( $_GET['chart'], 'admin-bar-hours' ) === 0 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
) {
global $wp_db_version;
return $wp_db_version;
@@ -154,7 +156,7 @@ function stats_map_meta_caps( $caps, $cap, $user_id ) {
$stats_roles = stats_get_option( 'roles' );
// Is the users role in the available stats roles?
- if ( is_array( $stats_roles ) && in_array( $user_role, $stats_roles ) ) {
+ if ( is_array( $stats_roles ) && in_array( $user_role, $stats_roles, true ) ) {
$caps = array( 'read' );
}
}
@@ -171,7 +173,20 @@ function stats_map_meta_caps( $caps, $cap, $user_id ) {
function stats_template_redirect() {
global $current_user;
- if ( is_feed() || is_robots() || is_trackback() || is_preview() || jetpack_is_dnt_enabled() ) {
+ if (
+ is_feed()
+ || is_robots()
+ || is_embed()
+ || is_trackback()
+ || is_preview()
+ || jetpack_is_dnt_enabled()
+ ) {
+ return;
+ }
+
+ // Staging Sites should not generate tracking stats.
+ $status = new Status();
+ if ( $status->is_staging_site() ) {
return;
}
@@ -184,10 +199,10 @@ function stats_template_redirect() {
}
add_action( 'wp_footer', 'stats_footer', 101 );
+ add_action( 'web_stories_print_analytics', 'stats_footer' );
}
-
/**
* Stats Build View Data.
*
@@ -197,12 +212,12 @@ function stats_template_redirect() {
function stats_build_view_data() {
global $wp_the_query;
- $blog = Jetpack_Options::get_option( 'id' );
- $tz = get_option( 'gmt_offset' );
- $v = 'ext';
+ $blog = Jetpack_Options::get_option( 'id' );
+ $tz = get_option( 'gmt_offset' );
+ $v = 'ext';
$blog_url = wp_parse_url( site_url() );
- $srv = $blog_url['host'];
- $j = sprintf( '%s:%s', JETPACK__API_VERSION, JETPACK__VERSION );
+ $srv = $blog_url['host'];
+ $j = sprintf( '%s:%s', JETPACK__API_VERSION, JETPACK__VERSION );
if ( $wp_the_query->is_single || $wp_the_query->is_page || $wp_the_query->is_posts_page ) {
// Store and reset the queried_object and queried_object_id
// Otherwise, redirect_canonical() will redirect to home_url( '/' ) for show_on_front = page sites where home_url() is not all lowercase.
@@ -211,11 +226,15 @@ function stats_build_view_data() {
// 2. Set show_on_front = page
// 3. Set page_on_front = something
// 4. Visit https://example.com/ !
- $queried_object = ( isset( $wp_the_query->queried_object ) ) ? $wp_the_query->queried_object : null;
- $queried_object_id = ( isset( $wp_the_query->queried_object_id ) ) ? $wp_the_query->queried_object_id : null;
- $post = $wp_the_query->get_queried_object_id();
- $wp_the_query->queried_object = $queried_object;
- $wp_the_query->queried_object_id = $queried_object_id;
+ $queried_object = isset( $wp_the_query->queried_object ) ? $wp_the_query->queried_object : null;
+ $queried_object_id = isset( $wp_the_query->queried_object_id ) ? $wp_the_query->queried_object_id : null;
+ try {
+ $post_obj = $wp_the_query->get_queried_object();
+ $post = $post_obj instanceof WP_Post ? $post_obj->ID : '0';
+ } finally {
+ $wp_the_query->queried_object = $queried_object;
+ $wp_the_query->queried_object_id = $queried_object_id;
+ }
} else {
$post = '0';
}
@@ -223,7 +242,6 @@ function stats_build_view_data() {
return compact( 'v', 'j', 'blog', 'post', 'tz', 'srv' );
}
-
/**
* Stats Footer.
*
@@ -240,22 +258,35 @@ function stats_footer() {
}
+/**
+ * Render the stats footer
+ *
+ * @param array $data Array of data for the JS stats tracker.
+ */
function stats_render_footer( $data ) {
- $script = 'https://stats.wp.com/e-' . gmdate( 'YW' ) . '.js';
+ // phpcs:disable WordPress.WP.EnqueuedResources.NonEnqueuedScript
+ // When there is a way to use defer with enqueue, we can move to it and inline the custom data.
+ $script = 'https://stats.wp.com/e-' . gmdate( 'YW' ) . '.js';
$data_stats_array = stats_array( $data );
$stats_footer = <<<END
-<script type='text/javascript' src='{$script}' async='async' defer='defer'></script>
-<script type='text/javascript'>
+<script src='{$script}' defer></script>
+<script>
_stq = window._stq || [];
_stq.push([ 'view', {{$data_stats_array}} ]);
_stq.push([ 'clickTrackerInit', '{$data['blog']}', '{$data['post']}' ]);
</script>
END;
- print $stats_footer;
+ // phpcs:enable
+ print $stats_footer; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
+/**
+ * Render the stats footer for AMP output.
+ *
+ * @param array $data Array of data for the JS stats tracker.
+ */
function stats_render_amp_footer( $data ) {
$data['host'] = isset( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : ''; // input var ok.
$data['rand'] = 'RANDOM'; // AMP placeholder.
@@ -346,7 +377,6 @@ function stats_upgrade_options( $options ) {
'count_roles' => array(),
'blog_id' => Jetpack_Options::get_option( 'id' ),
'do_not_track' => true, // @todo
- 'hide_smile' => true,
);
if ( isset( $options['reg_users'] ) ) {
@@ -361,7 +391,8 @@ function stats_upgrade_options( $options ) {
if ( is_array( $options ) && ! empty( $options ) ) {
$new_options = array_merge( $defaults, $options );
- } else { $new_options = $defaults;
+ } else {
+ $new_options = $defaults;
}
$new_options['version'] = STATS_VERSION;
@@ -370,17 +401,15 @@ function stats_upgrade_options( $options ) {
return false;
}
- stats_update_blog();
-
return $new_options;
}
/**
- * Stats Array.
+ * Creates the "array" string used as part of the JS tracker.
*
* @access public
- * @param mixed $kvs KVS.
- * @return array
+ * @param array $kvs KVS.
+ * @return string
*/
function stats_array( $kvs ) {
/**
@@ -392,8 +421,9 @@ function stats_array( $kvs ) {
*
* @param array $kvs Array of options about the site and page you're on.
*/
- $kvs = apply_filters( 'stats_array', $kvs );
- $kvs = array_map( 'addslashes', $kvs );
+ $kvs = (array) apply_filters( 'stats_array', $kvs );
+ $kvs = array_map( 'addslashes', $kvs );
+ $jskvs = array();
foreach ( $kvs as $k => $v ) {
$jskvs[] = "$k:'$v'";
}
@@ -411,7 +441,7 @@ function stats_admin_menu() {
// If we're at an old Stats URL, redirect to the new one.
// Don't even bother with caps, menu_page_url(), etc. Just do it.
- if ( 'index.php' === $pagenow && isset( $_GET['page'] ) && 'stats' === $_GET['page'] ) {
+ if ( 'index.php' === $pagenow && isset( $_GET['page'] ) && 'stats' === $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$redirect_url = str_replace( array( '/wp-admin/index.php?', '/wp-admin/?' ), '/wp-admin/admin.php?', $_SERVER['REQUEST_URI'] );
$relative_pos = strpos( $redirect_url, '/wp-admin/' );
if ( false !== $relative_pos ) {
@@ -441,6 +471,9 @@ function stats_admin_path() {
* @return void
*/
function stats_reports_load() {
+ require_once __DIR__ . '/stats/class-jetpack-stats-upgrade-nudges.php';
+ Jetpack_Stats_Upgrade_Nudges::init();
+
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'postbox' );
wp_enqueue_script( 'underscore' );
@@ -448,7 +481,7 @@ function stats_reports_load() {
Jetpack_Admin_Page::load_wrapper_styles();
add_action( 'admin_print_styles', 'stats_reports_css' );
- if ( isset( $_GET['nojs'] ) && $_GET['nojs'] ) {
+ if ( isset( $_GET['nojs'] ) && $_GET['nojs'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$parsed = wp_parse_url( admin_url() );
// Remember user doesn't want JS.
setcookie( 'stnojs', '1', time() + 172800, $parsed['path'] ); // 2 days.
@@ -457,7 +490,7 @@ function stats_reports_load() {
if ( isset( $_COOKIE['stnojs'] ) && $_COOKIE['stnojs'] ) {
// Detect if JS is on. If so, remove cookie so next page load is via JS.
add_action( 'admin_print_footer_scripts', 'stats_js_remove_stnojs_cookie' );
- } else if ( ! isset( $_GET['noheader'] ) && empty( $_GET['nojs'] ) ) {
+ } elseif ( ! isset( $_GET['noheader'] ) && empty( $_GET['nojs'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
// Normal page load. Load page content via JS.
add_action( 'admin_print_footer_scripts', 'stats_js_load_page_via_ajax' );
}
@@ -470,9 +503,9 @@ function stats_reports_load() {
* @return void
*/
function stats_reports_css() {
-?>
+ ?>
<style type="text/css">
-#jp-stats-wrap {
+#jp-stats-wrap, #jp-stats-report-bottom {
max-width: 1040px;
margin: 0 auto;
overflow: hidden;
@@ -486,10 +519,9 @@ function stats_reports_css() {
line-height: 64px;
}
</style>
-<?php
+ <?php
}
-
/**
* Detect if JS is on. If so, remove cookie so next page load is via JS.
*
@@ -498,13 +530,13 @@ function stats_reports_css() {
*/
function stats_js_remove_stnojs_cookie() {
$parsed = wp_parse_url( admin_url() );
-?>
+ ?>
<script type="text/javascript">
/* <![CDATA[ */
document.cookie = 'stnojs=0; expires=Wed, 9 Mar 2011 16:55:50 UTC; path=<?php echo esc_js( $parsed['path'] ); ?>';
/* ]]> */
</script>
-<?php
+ <?php
}
/**
@@ -514,23 +546,27 @@ document.cookie = 'stnojs=0; expires=Wed, 9 Mar 2011 16:55:50 UTC; path=<?php ec
* @return void
*/
function stats_js_load_page_via_ajax() {
-?>
+ ?>
<script type="text/javascript">
/* <![CDATA[ */
if ( -1 == document.location.href.indexOf( 'noheader' ) ) {
jQuery( function( $ ) {
$.get( document.location.href + '&noheader', function( responseText ) {
$( '#stats-loading-wrap' ).replaceWith( responseText );
+ $( '#jp-stats-wrap' )[0].dispatchEvent( new Event( 'stats-loaded' ) );
} );
} );
}
/* ]]> */
</script>
-<?php
+ <?php
}
-function jetpack_admin_ui_stats_report_page_wrapper() {
- if( ! isset( $_GET['noheader'] ) && empty( $_GET['nojs'] ) && empty( $_COOKIE['stnojs'] ) ) {
+/**
+ * Jetpack Admin Page Wrapper.
+ */
+function jetpack_admin_ui_stats_report_page_wrapper() {
+ if ( ! isset( $_GET['noheader'] ) && empty( $_GET['nojs'] ) && empty( $_COOKIE['stnojs'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
Jetpack_Admin_Page::wrap_ui( 'stats_reports_page', array( 'is-wide' => true ) );
} else {
stats_reports_page();
@@ -546,132 +582,135 @@ function jetpack_admin_ui_stats_report_page_wrapper() {
*/
function stats_reports_page( $main_chart_only = false ) {
- if ( isset( $_GET['dashboard'] ) ) {
+ if ( isset( $_GET['dashboard'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
return stats_dashboard_widget_content();
}
- $blog_id = stats_get_option( 'blog_id' );
- $domain = Jetpack::build_raw_urls( get_home_url() );
+ $blog_id = stats_get_option( 'blog_id' );
+ $stats_url = Redirect::get_url( 'calypso-stats' );
- $jetpack_admin_url = admin_url() . 'admin.php?page=jetpack';
-
- if ( ! $main_chart_only && ! isset( $_GET['noheader'] ) && empty( $_GET['nojs'] ) && empty( $_COOKIE['stnojs'] ) ) {
+ if ( ! $main_chart_only && ! isset( $_GET['noheader'] ) && empty( $_GET['nojs'] ) && empty( $_COOKIE['stnojs'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$nojs_url = add_query_arg( 'nojs', '1' );
- $http = is_ssl() ? 'https' : 'http';
+ $http = is_ssl() ? 'https' : 'http';
// Loading message. No JS fallback message.
-?>
+ ?>
<div id="jp-stats-wrap">
<div class="wrap">
<h2><?php esc_html_e( 'Site Stats', 'jetpack' ); ?>
<?php
- if ( current_user_can( 'jetpack_manage_modules' ) ) :
- $i18n_headers = jetpack_get_module_i18n( 'stats' );
- ?>
+ if ( current_user_can( 'jetpack_manage_modules' ) ) :
+ $i18n_headers = jetpack_get_module_i18n( 'stats' );
+ ?>
<a
style="font-size:13px;"
href="<?php echo esc_url( admin_url( 'admin.php?page=jetpack#/settings?term=' . rawurlencode( $i18n_headers['name'] ) ) ); ?>"
>
- <?php esc_html_e( 'Configure', 'jetpack' ); ?>
+ <?php esc_html_e( 'Configure', 'jetpack' ); ?>
</a>
- <?php
+ <?php
endif;
+
+ /**
+ * Sets external resource URL.
+ *
+ * @module stats
+ *
+ * @since 1.4.0
+ * @todo Clean up various uses of this filter. It's seemingly filtering different types of images in different places.
+ *
+ * @param string $args URL of external resource.
+ */
+ $static_url = apply_filters( 'jetpack_static_url', "{$http}://en.wordpress.com/i/loading/loading-64.gif" );
?>
</h2>
</div>
<div id="stats-loading-wrap" class="wrap">
- <p class="hide-if-no-js"><img width="32" height="32" alt="<?php esc_attr_e( 'Loading&hellip;', 'jetpack' ); ?>" src="<?php
- echo esc_url(
- /**
- * Sets external resource URL.
- *
- * @module stats
- *
- * @since 1.4.0
- *
- * @param string $args URL of external resource.
- */
- apply_filters( 'jetpack_static_url', "{$http}://en.wordpress.com/i/loading/loading-64.gif" )
- ); ?>" /></p>
- <p style="font-size: 11pt; margin: 0;"><a href="https://wordpress.com/stats/<?php echo esc_attr( $domain ); ?>" target="_blank"><?php esc_html_e( 'View stats on WordPress.com right now', 'jetpack' ); ?></a></p>
+ <p class="hide-if-no-js"><img width="32" height="32" alt="<?php esc_attr_e( 'Loading&hellip;', 'jetpack' ); ?>" src="<?php echo esc_url( $static_url ); ?>" /></p>
+ <p style="font-size: 11pt; margin: 0;"><a href="<?php echo esc_url( $stats_url ); ?>" rel="noopener noreferrer" target="_blank"><?php esc_html_e( 'View stats on WordPress.com right now', 'jetpack' ); ?></a></p>
<p class="hide-if-js"><?php esc_html_e( 'Your Site Stats work better with JavaScript enabled.', 'jetpack' ); ?><br />
<a href="<?php echo esc_url( $nojs_url ); ?>"><?php esc_html_e( 'View Site Stats without JavaScript', 'jetpack' ); ?></a>.</p>
</div>
</div>
-<?php
+ <?php
return;
}
- $day = isset( $_GET['day'] ) && preg_match( '/^\d{4}-\d{2}-\d{2}$/', $_GET['day'] ) ? $_GET['day'] : false;
- $q = array(
+ $day = isset( $_GET['day'] ) && preg_match( '/^\d{4}-\d{2}-\d{2}$/', $_GET['day'] ) ? $_GET['day'] : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ $q = array(
'noheader' => 'true',
- 'proxy' => '',
- 'page' => 'stats',
- 'day' => $day,
- 'blog' => $blog_id,
- 'charset' => get_option( 'blog_charset' ),
- 'color' => get_user_option( 'admin_color' ),
- 'ssl' => is_ssl(),
- 'j' => sprintf( '%s:%s', JETPACK__API_VERSION, JETPACK__VERSION ),
+ 'proxy' => '',
+ 'page' => 'stats',
+ 'day' => $day,
+ 'blog' => $blog_id,
+ 'charset' => get_option( 'blog_charset' ),
+ 'color' => get_user_option( 'admin_color' ),
+ 'ssl' => is_ssl(),
+ 'j' => sprintf( '%s:%s', JETPACK__API_VERSION, JETPACK__VERSION ),
);
if ( get_locale() !== 'en_US' ) {
$q['jp_lang'] = get_locale();
}
// Only show the main chart, without extra header data, or metaboxes.
$q['main_chart_only'] = $main_chart_only;
- $args = array(
- 'view' => array( 'referrers', 'postviews', 'searchterms', 'clicks', 'post', 'table' ),
- 'numdays' => 'int',
- 'day' => 'date',
- 'unit' => array( 1, 7, 31, 'human' ),
- 'humanize' => array( 'true' ),
- 'num' => 'int',
- 'summarize' => null,
- 'post' => 'int',
- 'width' => 'int',
- 'height' => 'int',
- 'data' => 'data',
- 'blog_subscribers' => 'int',
+ $args = array(
+ 'view' => array( 'referrers', 'postviews', 'searchterms', 'clicks', 'post', 'table' ),
+ 'numdays' => 'int',
+ 'day' => 'date',
+ 'unit' => array( '1', '7', '31', 'human' ),
+ 'humanize' => array( 'true' ),
+ 'num' => 'int',
+ 'summarize' => null,
+ 'post' => 'int',
+ 'width' => 'int',
+ 'height' => 'int',
+ 'data' => 'data',
+ 'blog_subscribers' => 'int',
'comment_subscribers' => null,
- 'type' => array( 'wpcom', 'email', 'pending' ),
- 'pagenum' => 'int',
+ 'type' => array( 'wpcom', 'email', 'pending' ),
+ 'pagenum' => 'int',
+ 'masterbar' => null,
);
foreach ( $args as $var => $vals ) {
- if ( ! isset( $_REQUEST[$var] ) )
+ if ( ! isset( $_REQUEST[ $var ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
continue;
+ }
if ( is_array( $vals ) ) {
- if ( in_array( $_REQUEST[$var], $vals ) )
- $q[$var] = $_REQUEST[$var];
+ if ( in_array( $_REQUEST[ $var ], $vals, true ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ $q[ $var ] = $_REQUEST[ $var ]; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ }
} elseif ( 'int' === $vals ) {
- $q[$var] = intval( $_REQUEST[$var] );
+ $q[ $var ] = (int) $_REQUEST[ $var ]; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
} elseif ( 'date' === $vals ) {
- if ( preg_match( '/^\d{4}-\d{2}-\d{2}$/', $_REQUEST[$var] ) )
- $q[$var] = $_REQUEST[$var];
+ if ( preg_match( '/^\d{4}-\d{2}-\d{2}$/', $_REQUEST[ $var ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ $q[ $var ] = $_REQUEST[ $var ]; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ }
} elseif ( null === $vals ) {
- $q[$var] = '';
+ $q[ $var ] = '';
} elseif ( 'data' === $vals ) {
- if ( 'index.php' === substr( $_REQUEST[$var], 0, 9 ) )
- $q[$var] = $_REQUEST[$var];
+ if ( 'index.php' === substr( $_REQUEST[ $var ], 0, 9 ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ $q[ $var ] = $_REQUEST[ $var ];// phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ }
}
}
- if ( isset( $_GET['chart'] ) ) {
- if ( preg_match( '/^[a-z0-9-]+$/', $_GET['chart'] ) ) {
- $chart = sanitize_title( $_GET['chart'] );
- $url = 'https://' . STATS_DASHBOARD_SERVER . "/wp-includes/charts/{$chart}.php";
+ if ( isset( $_GET['chart'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ if ( preg_match( '/^[a-z0-9-]+$/', $_GET['chart'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ $chart = sanitize_title( $_GET['chart'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ $url = 'https://' . STATS_DASHBOARD_SERVER . "/wp-includes/charts/{$chart}.php";
}
} else {
- $url = 'https://' . STATS_DASHBOARD_SERVER . "/wp-admin/index.php";
+ $url = 'https://' . STATS_DASHBOARD_SERVER . '/wp-admin/index.php';
}
- $url = add_query_arg( $q, $url );
- $method = 'GET';
+ $url = add_query_arg( $q, $url );
+ $method = 'GET';
$timeout = 90;
- $user_id = JETPACK_MASTER_USER; // means send the wp.com user_id
+ $user_id = 0; // Means use the blog token.
- $get = Client::remote_request( compact( 'url', 'method', 'timeout', 'user_id' ) );
+ $get = Client::remote_request( compact( 'url', 'method', 'timeout', 'user_id' ) );
$get_code = wp_remote_retrieve_response_code( $get );
- if ( is_wp_error( $get ) || ( 2 !== intval( $get_code / 100 ) && 304 !== $get_code ) || empty( $get['body'] ) ) {
+ if ( is_wp_error( $get ) || ( 2 !== (int) ( $get_code / 100 ) && 304 !== $get_code ) || empty( $get['body'] ) ) {
stats_print_wp_remote_error( $get, $url );
} else {
if ( ! empty( $get['headers']['content-type'] ) ) {
@@ -680,7 +719,7 @@ function stats_reports_page( $main_chart_only = false ) {
$img = $get['body'];
header( 'Content-Type: ' . $type );
header( 'Content-Length: ' . strlen( $img ) );
- echo $img;
+ echo $img; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
die();
}
}
@@ -688,15 +727,15 @@ function stats_reports_page( $main_chart_only = false ) {
$body = stats_convert_chart_urls( $body );
$body = stats_convert_image_urls( $body );
$body = stats_convert_admin_urls( $body );
- echo $body;
+ echo $body; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
- if ( isset( $_GET['page'] ) && 'stats' === $_GET['page'] && ! isset( $_GET['chart'] ) ) {
+ if ( isset( $_GET['page'] ) && 'stats' === $_GET['page'] && ! isset( $_GET['chart'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$tracking = new Tracking();
- $tracking->record_user_event( 'wpa_page_view', array( 'path' => 'old_stats' ) );
+ $tracking->record_user_event( 'wpa_page_view', array( 'path' => 'old_stats' ) );
}
- if ( isset( $_GET['noheader'] ) ) {
+ if ( isset( $_GET['noheader'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
die;
}
}
@@ -720,7 +759,7 @@ function stats_convert_admin_urls( $html ) {
* @return string
*/
function stats_convert_image_urls( $html ) {
- $url = set_url_scheme( 'https://' . STATS_DASHBOARD_SERVER );
+ $url = set_url_scheme( 'https://' . STATS_DASHBOARD_SERVER );
$html = preg_replace( '|(["\'])(/i/stats.+)\\1|', '$1' . $url . '$2$1', $html );
return $html;
}
@@ -730,7 +769,7 @@ function stats_convert_image_urls( $html ) {
*
* @since 5.6.0
*
- * @param array $matches The matches resulting from the preg_replace_callback call.
+ * @param array $matches The matches resulting from the preg_replace_callback call.
* @return string The admin url for the chart.
*/
function jetpack_stats_convert_chart_urls_callback( $matches ) {
@@ -769,10 +808,10 @@ function stats_convert_post_titles( $html ) {
}
$posts = get_posts(
array(
- 'include' => implode( ',', $matches[1] ),
- 'post_type' => 'any',
- 'post_status' => 'any',
- 'numberposts' => -1,
+ 'include' => implode( ',', $matches[1] ),
+ 'post_type' => 'any',
+ 'post_status' => 'any',
+ 'numberposts' => -1,
'suppress_filters' => false,
)
);
@@ -793,23 +832,23 @@ function stats_convert_post_titles( $html ) {
function stats_convert_post_title( $matches ) {
global $stats_posts;
$post_id = $matches[1];
- if ( isset( $stats_posts[$post_id] ) )
+ if ( isset( $stats_posts[ $post_id ] ) ) {
return '<a href="' . get_permalink( $post_id ) . '" target="_blank">' . get_the_title( $post_id ) . '</a>';
+ }
return $matches[0];
}
/**
- * Stats Hide Smile.
+ * CSS to hide the tracking pixel smiley.
+ * It is now hidden for everyone (used to be visible if you had set the hide_smile option).
*
* @access public
* @return void
*/
function stats_hide_smile_css() {
- $options = stats_get_options();
- if ( isset( $options['hide_smile'] ) && $options['hide_smile'] ) {
-?>
-<style type='text/css'>img#wpstats{display:none}</style><?php
- }
+ ?>
+<style type='text/css'>img#wpstats{display:none}</style>
+ <?php
}
/**
@@ -819,18 +858,20 @@ function stats_hide_smile_css() {
* @return void
*/
function stats_admin_bar_head() {
- if ( ! stats_get_option( 'admin_bar' ) )
+ if ( ! stats_get_option( 'admin_bar' ) ) {
return;
+ }
- if ( ! current_user_can( 'view_stats' ) )
+ if ( ! current_user_can( 'view_stats' ) ) {
return;
+ }
if ( ! is_admin_bar_showing() ) {
return;
}
add_action( 'admin_bar_menu', 'stats_admin_bar_menu', 100 );
-?>
+ ?>
<style data-ampdevmode type='text/css'>
#wpadminbar .quicklinks li#wp-admin-bar-stats {
@@ -857,7 +898,30 @@ function stats_admin_bar_head() {
border: none;
}
</style>
-<?php
+ <?php
+}
+
+/**
+ * Gets the image source of the given stats chart.
+ *
+ * @param string $chart Name of the chart.
+ * @param array $args Extra list of argument to use in the image source.
+ * @return string An image source.
+ */
+function stats_get_image_chart_src( $chart, $args = array() ) {
+ $url = add_query_arg( 'page', 'stats', admin_url( 'admin.php' ) );
+
+ return add_query_arg(
+ array_merge(
+ array(
+ 'noheader' => '',
+ 'proxy' => '',
+ 'chart' => $chart,
+ ),
+ $args
+ ),
+ $url
+ );
}
/**
@@ -868,18 +932,14 @@ function stats_admin_bar_head() {
* @return void
*/
function stats_admin_bar_menu( &$wp_admin_bar ) {
- $url = add_query_arg( 'page', 'stats', admin_url( 'admin.php' ) ); // no menu_page_url() blog-side.
-
- $img_src = esc_attr( add_query_arg( array( 'noheader' => '', 'proxy' => '', 'chart' => 'admin-bar-hours-scale' ), $url ) );
- $img_src_2x = esc_attr( add_query_arg( array( 'noheader' => '', 'proxy' => '', 'chart' => 'admin-bar-hours-scale-2x' ), $url ) );
-
- $alt = esc_attr( __( 'Stats', 'jetpack' ) );
-
- $title = esc_attr( __( 'Views over 48 hours. Click for more Site Stats.', 'jetpack' ) );
+ $img_src = esc_attr( stats_get_image_chart_src( 'admin-bar-hours-scale' ) );
+ $img_src_2x = esc_attr( stats_get_image_chart_src( 'admin-bar-hours-scale-2x' ) );
+ $alt = esc_attr( __( 'Stats', 'jetpack' ) );
+ $title = esc_attr( __( 'Views over 48 hours. Click for more Site Stats.', 'jetpack' ) );
$menu = array(
'id' => 'stats',
- 'href' => $url,
+ 'href' => add_query_arg( 'page', 'stats', admin_url( 'admin.php' ) ), // no menu_page_url() blog-side.
'title' => "<div><img src='$img_src' srcset='$img_src 1x, $img_src_2x 2x' width='112' height='24' alt='$alt' title='$title'></div>",
);
@@ -887,13 +947,19 @@ function stats_admin_bar_menu( &$wp_admin_bar ) {
}
/**
+ *
+ * Deprecated. The stats module should not update blog details. This is handled by Sync.
+ *
* Stats Update Blog.
*
* @access public
* @return void
+ *
+ * @deprecated since 10.3.
*/
function stats_update_blog() {
- Jetpack::xmlrpc_async_call( 'jetpack.updateBlog', stats_get_blog() );
+ deprecated_function( __METHOD__, 'jetpack-10.3' );
+ XMLRPC_Async_Call::add_call( 'jetpack.updateBlog', 0, stats_get_blog() );
}
/**
@@ -962,37 +1028,26 @@ function stats_xmlrpc_methods( $methods ) {
}
/**
- * Register Stats Dashboard Widget.
- *
- * @access public
- * @return void
- */
-function stats_register_dashboard_widget() {
- if ( ! current_user_can( 'view_stats' ) )
- return;
-
- // With wp_dashboard_empty: we load in the content after the page load via JS.
- wp_add_dashboard_widget( 'dashboard_stats', __( 'Site Stats', 'jetpack' ), 'wp_dashboard_empty', 'stats_dashboard_widget_control' );
-
- add_action( 'admin_head', 'stats_dashboard_head' );
-}
-
-/**
* Stats Dashboard Widget Options.
*
* @access public
* @return array
*/
function stats_dashboard_widget_options() {
- $defaults = array( 'chart' => 1, 'top' => 1, 'search' => 7 );
- if ( ( ! $options = get_option( 'stats_dashboard_widget' ) ) || ! is_array( $options ) ) {
+ $defaults = array(
+ 'chart' => 1,
+ 'top' => 1,
+ 'search' => 7,
+ );
+ $options = get_option( 'stats_dashboard_widget' );
+ if ( ( ! $options ) || ! is_array( $options ) ) {
$options = array();
}
// Ignore obsolete option values.
$intervals = array( 1, 7, 31, 90, 365 );
foreach ( array( 'top', 'search' ) as $key ) {
- if ( isset( $options[ $key ] ) && ! in_array( $options[ $key ], $intervals ) ) {
+ if ( isset( $options[ $key ] ) && ! in_array( (int) $options[ $key ], $intervals, true ) ) {
unset( $options[ $key ] );
}
}
@@ -1008,47 +1063,48 @@ function stats_dashboard_widget_options() {
*/
function stats_dashboard_widget_control() {
$periods = array(
- '1' => __( 'day', 'jetpack' ),
- '7' => __( 'week', 'jetpack' ),
+ '1' => __( 'day', 'jetpack' ),
+ '7' => __( 'week', 'jetpack' ),
'31' => __( 'month', 'jetpack' ),
);
$intervals = array(
- '1' => __( 'the past day', 'jetpack' ),
- '7' => __( 'the past week', 'jetpack' ),
- '31' => __( 'the past month', 'jetpack' ),
- '90' => __( 'the past quarter', 'jetpack' ),
+ '1' => __( 'the past day', 'jetpack' ),
+ '7' => __( 'the past week', 'jetpack' ),
+ '31' => __( 'the past month', 'jetpack' ),
+ '90' => __( 'the past quarter', 'jetpack' ),
'365' => __( 'the past year', 'jetpack' ),
);
- $defaults = array(
- 'top' => 1,
+ $defaults = array(
+ 'top' => 1,
'search' => 7,
);
$options = stats_dashboard_widget_options();
- if ( 'post' === strtolower( $_SERVER['REQUEST_METHOD'] ) && isset( $_POST['widget_id'] ) && 'dashboard_stats' === $_POST['widget_id'] ) {
- if ( isset( $periods[ $_POST['chart'] ] ) ) {
- $options['chart'] = $_POST['chart'];
+ if ( 'post' === strtolower( $_SERVER['REQUEST_METHOD'] ) && isset( $_POST['widget_id'] ) && 'dashboard_stats' === $_POST['widget_id'] ) { // phpcs:ignore WordPress.Security.NonceVerification
+ if ( isset( $periods[ $_POST['chart'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
+ $options['chart'] = $_POST['chart']; // phpcs:ignore WordPress.Security.NonceVerification
}
foreach ( array( 'top', 'search' ) as $key ) {
- if ( isset( $intervals[ $_POST[ $key ] ] ) ) {
- $options[ $key ] = $_POST[ $key ];
- } else { $options[ $key ] = $defaults[ $key ];
+ if ( isset( $intervals[ $_POST[ $key ] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
+ $options[ $key ] = $_POST[ $key ]; // phpcs:ignore WordPress.Security.NonceVerification
+ } else {
+ $options[ $key ] = $defaults[ $key ];
}
}
update_option( 'stats_dashboard_widget', $options );
}
-?>
+ ?>
<p>
- <label for="chart"><?php esc_html_e( 'Chart stats by' , 'jetpack' ); ?></label>
+ <label for="chart"><?php esc_html_e( 'Chart stats by', 'jetpack' ); ?></label>
<select id="chart" name="chart">
<?php
foreach ( $periods as $val => $label ) {
-?>
- <option value="<?php echo $val; ?>"<?php selected( $val, $options['chart'] ); ?>><?php echo esc_html( $label ); ?></option>
+ ?>
+ <option value="<?php echo esc_attr( $val ); ?>"<?php selected( $val, $options['chart'] ); ?>><?php echo esc_html( $label ); ?></option>
<?php
}
-?>
+ ?>
</select>.
</p>
@@ -1057,11 +1113,11 @@ function stats_dashboard_widget_control() {
<select id="top" name="top">
<?php
foreach ( $intervals as $val => $label ) {
-?>
- <option value="<?php echo $val; ?>"<?php selected( $val, $options['top'] ); ?>><?php echo esc_html( $label ); ?></option>
+ ?>
+ <option value="<?php echo esc_attr( $val ); ?>"<?php selected( $val, $options['top'] ); ?>><?php echo esc_html( $label ); ?></option>
<?php
}
-?>
+ ?>
</select>.
</p>
@@ -1070,11 +1126,11 @@ function stats_dashboard_widget_control() {
<select id="search" name="search">
<?php
foreach ( $intervals as $val => $label ) {
-?>
- <option value="<?php echo $val; ?>"<?php selected( $val, $options['search'] ); ?>><?php echo esc_html( $label ); ?></option>
+ ?>
+ <option value="<?php echo esc_attr( $val ); ?>"<?php selected( $val, $options['search'] ); ?>><?php echo esc_html( $label ); ?></option>
<?php
}
-?>
+ ?>
</select>.
</p>
<?php
@@ -1087,79 +1143,33 @@ function stats_dashboard_widget_control() {
* @return void
*/
function stats_jetpack_dashboard_widget() {
-?>
+ ?>
<form id="stats_dashboard_widget_control" action="<?php echo esc_url( admin_url() ); ?>" method="post">
<?php stats_dashboard_widget_control(); ?>
<?php wp_nonce_field( 'edit-dashboard-widget_dashboard_stats', 'dashboard-widget-nonce' ); ?>
<input type="hidden" name="widget_id" value="dashboard_stats" />
<?php submit_button( __( 'Submit', 'jetpack' ) ); ?>
</form>
- <span class="js-toggle-stats_dashboard_widget_control">
- <?php esc_html_e( 'Configure', 'jetpack' ); ?>
- </span>
+ <button type="button" class="handlediv js-toggle-stats_dashboard_widget_control" aria-expanded="true">
+ <span class="screen-reader-text"><?php esc_html_e( 'Configure', 'jetpack' ); ?></span>
+ <span class="toggle-indicator" aria-hidden="true"></span>
+ </button>
<div id="dashboard_stats">
<div class="inside">
<div style="height: 250px;"></div>
</div>
</div>
- <script>
- jQuery(document).ready(function($){
- var $toggle = $('.js-toggle-stats_dashboard_widget_control');
-
- $toggle.parent().prev().append( $toggle );
- $toggle.show().click(function(e){
- e.preventDefault();
- e.stopImmediatePropagation();
- $(this).parent().toggleClass('controlVisible');
- $('#stats_dashboard_widget_control').slideToggle();
- });
- });
- </script>
- <style>
- .js-toggle-stats_dashboard_widget_control {
- display: none;
- float: right;
- margin-top: 0.2em;
- font-weight: 400;
- color: #444;
- font-size: .8em;
- text-decoration: underline;
- cursor: pointer;
- }
- #stats_dashboard_widget_control {
- display: none;
- padding: 0 10px;
- overflow: hidden;
- }
- #stats_dashboard_widget_control .button-primary {
- float: right;
- }
- #dashboard_stats {
- box-sizing: border-box;
- width: 100%;
- padding: 0 10px;
- }
- </style>
<?php
}
/**
- * Register Stats Widget Control Callback.
- *
- * @access public
- * @return void
- */
-function stats_register_widget_control_callback() {
- $GLOBALS['wp_dashboard_control_callbacks']['dashboard_stats'] = 'stats_dashboard_widget_control';
-}
-
-/**
* JavaScript and CSS for dashboard widget.
*
* @access public
* @return void
*/
-function stats_dashboard_head() { ?>
+function stats_dashboard_head() {
+ ?>
<script type="text/javascript">
/* <![CDATA[ */
jQuery( function($) {
@@ -1188,82 +1198,25 @@ jQuery( function($) {
jQuery( window ).one( 'resize', function() {
jQuery( '#stat-chart' ).css( 'width', 'auto' );
} );
+
+
+ // Widget settings toggle container.
+ var toggle = $( '.js-toggle-stats_dashboard_widget_control' );
+
+ // Move the toggle in the widget header.
+ toggle.appendTo( '#jetpack_summary_widget .handle-actions' );
+
+ // Toggle settings when clicking on it.
+ toggle.show().click( function( e ) {
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ $( this ).parent().toggleClass( 'controlVisible' );
+ $( '#stats_dashboard_widget_control' ).slideToggle();
+ } );
} );
/* ]]> */
</script>
-<style type="text/css">
-/* <![CDATA[ */
-#stat-chart {
- background: none !important;
-}
-#dashboard_stats .inside {
- margin: 10px 0 0 0 !important;
-}
-#dashboard_stats #stats-graph {
- margin: 0;
-}
-#stats-info {
- border-top: 1px solid #dfdfdf;
- margin: 7px -10px 0 -10px;
- padding: 10px;
- background: #fcfcfc;
- -moz-box-shadow:inset 0 1px 0 #fff;
- -webkit-box-shadow:inset 0 1px 0 #fff;
- box-shadow:inset 0 1px 0 #fff;
- overflow: hidden;
- border-radius: 0 0 2px 2px;
- -webkit-border-radius: 0 0 2px 2px;
- -moz-border-radius: 0 0 2px 2px;
- -khtml-border-radius: 0 0 2px 2px;
-}
-#stats-info #top-posts, #stats-info #top-search {
- float: left;
- width: 50%;
-}
-#stats-info #top-posts {
- padding-right: 3%;
-}
-#top-posts .stats-section-inner p {
- white-space: nowrap;
- overflow: hidden;
-}
-#top-posts .stats-section-inner p a {
- overflow: hidden;
- text-overflow: ellipsis;
-}
-#stats-info div#active {
- border-top: 1px solid #dfdfdf;
- margin: 0 -10px;
- padding: 10px 10px 0 10px;
- -moz-box-shadow:inset 0 1px 0 #fff;
- -webkit-box-shadow:inset 0 1px 0 #fff;
- box-shadow:inset 0 1px 0 #fff;
- overflow: hidden;
-}
-#top-search p {
- color: #999;
-}
-#stats-info h3 {
- font-size: 1em;
- margin: 0 0 .5em 0 !important;
-}
-#stats-info p {
- margin: 0 0 .25em;
- color: #999;
-}
-#stats-info p.widget-loading {
- margin: 1em 0 0;
- color: #333;
-}
-#stats-info p a {
- display: block;
-}
-#stats-info p a.button {
- display: inline;
-}
-/* ]]> */
-</style>
-<?php
+ <?php
}
/**
@@ -1273,61 +1226,65 @@ jQuery( function($) {
* @return void
*/
function stats_dashboard_widget_content() {
- if ( ! isset( $_GET['width'] ) || ( ! $width = (int) ( $_GET['width'] / 2 ) ) || $width < 250 ) {
+ $width = isset( $_GET['width'] ) ? (int) ( $_GET['width'] / 2 ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ $height = isset( $_GET['height'] ) ? (int) $_GET['height'] - 36 : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ if ( ! $width || $width < 250 ) {
$width = 370;
}
- if ( ! isset( $_GET['height'] ) || ( ! $height = (int) $_GET['height'] - 36 ) || $height < 230 ) {
+ if ( ! $height || $height < 230 ) {
$height = 180;
}
- $_width = $width - 5;
- $_height = $height - ( $GLOBALS['is_winIE'] ? 16 : 5 ); // Hack!
+ $_width = $width - 5;
+ $_height = $height - 5;
$options = stats_dashboard_widget_options();
$blog_id = Jetpack_Options::get_option( 'id' );
$q = array(
'noheader' => 'true',
- 'proxy' => '',
- 'blog' => $blog_id,
- 'page' => 'stats',
- 'chart' => '',
- 'unit' => $options['chart'],
- 'color' => get_user_option( 'admin_color' ),
- 'width' => $_width,
- 'height' => $_height,
- 'ssl' => is_ssl(),
- 'j' => sprintf( '%s:%s', JETPACK__API_VERSION, JETPACK__VERSION ),
+ 'proxy' => '',
+ 'blog' => $blog_id,
+ 'page' => 'stats',
+ 'chart' => '',
+ 'unit' => $options['chart'],
+ 'color' => get_user_option( 'admin_color' ),
+ 'width' => $_width,
+ 'height' => $_height,
+ 'ssl' => is_ssl(),
+ 'j' => sprintf( '%s:%s', JETPACK__API_VERSION, JETPACK__VERSION ),
);
- $url = 'https://' . STATS_DASHBOARD_SERVER . "/wp-admin/index.php";
+ $url = 'https://' . STATS_DASHBOARD_SERVER . '/wp-admin/index.php';
- $url = add_query_arg( $q, $url );
- $method = 'GET';
+ $url = add_query_arg( $q, $url );
+ $method = 'GET';
$timeout = 90;
- $user_id = JETPACK_MASTER_USER;
+ $user_id = 0; // Means use the blog token.
- $get = Client::remote_request( compact( 'url', 'method', 'timeout', 'user_id' ) );
+ $get = Client::remote_request( compact( 'url', 'method', 'timeout', 'user_id' ) );
$get_code = wp_remote_retrieve_response_code( $get );
- if ( is_wp_error( $get ) || ( 2 !== intval( $get_code / 100 ) && 304 !== $get_code ) || empty( $get['body'] ) ) {
+ if ( is_wp_error( $get ) || ( 2 !== (int) ( $get_code / 100 ) && 304 !== $get_code ) || empty( $get['body'] ) ) {
stats_print_wp_remote_error( $get, $url );
} else {
$body = stats_convert_post_titles( $get['body'] );
$body = stats_convert_chart_urls( $body );
$body = stats_convert_image_urls( $body );
- echo $body;
+ echo $body; // phpcs:ignore WordPress.Security.EscapeOutput
}
$post_ids = array();
- $csv_end_date = date( 'Y-m-d', current_time( 'timestamp' ) );
- $csv_args = array( 'top' => "&limit=8&end=$csv_end_date", 'search' => "&limit=5&end=$csv_end_date" );
- /* Translators: Stats dashboard widget postviews list: "$post_title $views Views". */
- $printf = __( '%1$s %2$s Views' , 'jetpack' );
+ $csv_end_date = current_time( 'Y-m-d' );
+ $csv_args = array(
+ 'top' => "&limit=8&end=$csv_end_date",
+ 'search' => "&limit=5&end=$csv_end_date",
+ );
- foreach ( $top_posts = stats_get_csv( 'postviews', "days=$options[top]$csv_args[top]" ) as $i => $post ) {
+ $top_posts = stats_get_csv( 'postviews', "days=$options[top]$csv_args[top]" );
+ foreach ( $top_posts as $i => $post ) {
if ( 0 === $post['post_id'] ) {
- unset( $top_posts[$i] );
+ unset( $top_posts[ $i ] );
continue;
}
$post_ids[] = $post['post_id'];
@@ -1336,73 +1293,82 @@ function stats_dashboard_widget_content() {
// Cache.
get_posts( array( 'include' => join( ',', array_unique( $post_ids ) ) ) );
- $searches = array();
- foreach ( $search_terms = stats_get_csv( 'searchterms', "days=$options[search]$csv_args[search]" ) as $search_term ) {
+ $searches = array();
+ $search_terms = stats_get_csv( 'searchterms', "days=$options[search]$csv_args[search]" );
+ foreach ( $search_terms as $search_term ) {
if ( 'encrypted_search_terms' === $search_term['searchterm'] ) {
continue;
}
$searches[] = esc_html( $search_term['searchterm'] );
}
-?>
+ ?>
<div id="stats-info">
<div id="top-posts" class='stats-section'>
<div class="stats-section-inner">
- <h3 class="heading"><?php esc_html_e( 'Top Posts' , 'jetpack' ); ?></h3>
+ <h3 class="heading"><?php esc_html_e( 'Top Posts', 'jetpack' ); ?></h3>
<?php
- if ( empty( $top_posts ) ) {
-?>
- <p class="nothing"><?php esc_html_e( 'Sorry, nothing to report.', 'jetpack' ); ?></p>
+ if ( empty( $top_posts ) ) {
+ ?>
+ <p class="nothing"><?php esc_html_e( 'Sorry, nothing to report.', 'jetpack' ); ?></p>
<?php
- } else {
- foreach ( $top_posts as $post ) {
- if ( ! get_post( $post['post_id'] ) ) {
- continue;
- }
-?>
- <p><?php printf(
- $printf,
- '<a href="' . get_permalink( $post['post_id'] ) . '">' . get_the_title( $post['post_id'] ) . '</a>',
- number_format_i18n( $post['views'] )
- ); ?></p>
+ } else {
+ foreach ( $top_posts as $post ) {
+ if ( ! get_post( $post['post_id'] ) ) {
+ continue;
+ }
+ ?>
+ <p>
<?php
+ printf(
+ esc_html(
+ /* Translators: Stats dashboard widget Post list with view count: "Post Title 1 View (or Views if plural)". */
+ _n( '%1$s %2$s View', '%1$s %2$s Views', $post['views'], 'jetpack' )
+ ),
+ '<a href="' . esc_url( get_permalink( $post['post_id'] ) ) . '">' . esc_html( get_the_title( $post['post_id'] ) ) . '</a>',
+ esc_html( number_format_i18n( $post['views'] ) )
+ );
+ ?>
+ </p>
+ <?php
+ }
}
- }
-?>
+ ?>
</div>
</div>
<div id="top-search" class='stats-section'>
<div class="stats-section-inner">
- <h3 class="heading"><?php esc_html_e( 'Top Searches' , 'jetpack' ); ?></h3>
+ <h3 class="heading"><?php esc_html_e( 'Top Searches', 'jetpack' ); ?></h3>
<?php
- if ( empty( $searches ) ) {
-?>
- <p class="nothing"><?php esc_html_e( 'Sorry, nothing to report.', 'jetpack' ); ?></p>
+ if ( empty( $searches ) ) {
+ ?>
+ <p class="nothing"><?php esc_html_e( 'Sorry, nothing to report.', 'jetpack' ); ?></p>
<?php
- } else {
- foreach ( $searches as $search_term_item ) {
- printf(
- '<p>%s</p>',
- $search_term_item
- );
+ } else {
+ foreach ( $searches as $search_term_item ) {
+ printf(
+ '<p>%s</p>',
+ esc_html( $search_term_item )
+ );
+ }
}
- }
-?>
+ ?>
</div>
</div>
</div>
<div class="clear"></div>
<div class="stats-view-all">
-<?php
+ <?php
+ $stats_day_url = Redirect::get_url( 'calypso-stats-day' );
printf(
'<a class="button" target="_blank" rel="noopener noreferrer" href="%1$s">%2$s</a>',
- esc_url( "https://wordpress.com/stats/day/" . Jetpack::build_raw_urls( get_home_url() ) ),
+ esc_url( $stats_day_url ),
esc_html__( 'View all stats', 'jetpack' )
);
-?>
+ ?>
</div>
<div class="clear"></div>
-<?php
+ <?php
exit;
}
@@ -1415,45 +1381,57 @@ function stats_dashboard_widget_content() {
* @return void
*/
function stats_print_wp_remote_error( $get, $url ) {
- $state_name = 'stats_remote_error_' . substr( md5( $url ), 0, 8 );
+ $state_name = 'stats_remote_error_' . substr( md5( $url ), 0, 8 );
$previous_error = Jetpack::state( $state_name );
- $error = md5( serialize( compact( 'get', 'url' ) ) );
+ $error = md5( wp_json_encode( compact( 'get', 'url' ) ) );
Jetpack::state( $state_name, $error );
if ( $error !== $previous_error ) {
-?>
+ ?>
<div class="wrap">
<p><?php esc_html_e( 'We were unable to get your stats just now. Please reload this page to try again.', 'jetpack' ); ?></p>
</div>
-<?php
+ <?php
return;
}
-?>
+ ?>
<div class="wrap">
- <p><?php printf( __( 'We were unable to get your stats just now. Please reload this page to try again. If this error persists, please <a href="%1$s" target="_blank">contact support</a>. In your report please include the information below.', 'jetpack' ), 'https://support.wordpress.com/contact/?jetpack=needs-service' ); ?></p>
+ <p>
+ <?php
+ printf(
+ /* translators: placeholder is an a href for a support site. */
+ esc_html__( 'We were unable to get your stats just now. Please reload this page to try again. If this error persists, please contact %1$s. In your report, please include the information below.', 'jetpack' ),
+ sprintf(
+ '<a href="https://support.wordpress.com/contact/?jetpack=needs-service">%s</a>',
+ esc_html__( 'Jetpack Support', 'jetpack' )
+ )
+ );
+ ?>
+ </p>
<pre>
User Agent: "<?php echo esc_html( $_SERVER['HTTP_USER_AGENT'] ); ?>"
- Page URL: "http<?php echo (is_ssl()?'s':'') . '://' . esc_html( $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); ?>"
+ Page URL: "http<?php echo ( is_ssl() ? 's' : '' ) . '://' . esc_html( $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); ?>"
API URL: "<?php echo esc_url( $url ); ?>"
-<?php
-if ( is_wp_error( $get ) ) {
- foreach ( $get->get_error_codes() as $code ) {
- foreach ( $get->get_error_messages( $code ) as $message ) {
-?>
-<?php print $code . ': "' . $message . '"' ?>
+ <?php
+ if ( is_wp_error( $get ) ) {
+ foreach ( $get->get_error_codes() as $code ) {
+ foreach ( $get->get_error_messages( $code ) as $message ) {
+ ?>
+ <?php print esc_html( $code ) . ': "' . esc_html( $message ) . '"'; ?>
-<?php
+ <?php
+ }
}
- }
-} else {
- $get_code = wp_remote_retrieve_response_code( $get );
- $content_length = strlen( wp_remote_retrieve_body( $get ) );
-?>
-Response code: "<?php print $get_code ?>"
-Content length: "<?php print $content_length ?>"
+ } else {
+ $get_code = wp_remote_retrieve_response_code( $get );
+ $content_length = strlen( wp_remote_retrieve_body( $get ) );
+ ?>
+Response code: "<?php print esc_html( $get_code ); ?>"
+Content length: "<?php print esc_html( $content_length ); ?>"
-<?php
-}
- ?></pre>
+ <?php
+ }
+ ?>
+ </pre>
</div>
<?php
}
@@ -1488,10 +1466,16 @@ Content length: "<?php print $content_length ?>"
* }
*/
function stats_get_csv( $table, $args = null ) {
- $defaults = array( 'end' => false, 'days' => false, 'limit' => 3, 'post_id' => false, 'summarize' => '' );
+ $defaults = array(
+ 'end' => false,
+ 'days' => false,
+ 'limit' => 3,
+ 'post_id' => false,
+ 'summarize' => '',
+ );
- $args = wp_parse_args( $args, $defaults );
- $args['table'] = $table;
+ $args = wp_parse_args( $args, $defaults );
+ $args['table'] = $table;
$args['blog_id'] = Jetpack_Options::get_option( 'id' );
$stats_csv_url = add_query_arg( $args, 'https://stats.wordpress.com/csv.php' );
@@ -1515,7 +1499,8 @@ function stats_get_csv( $table, $args = null ) {
$stats_rows = array();
do {
- if ( ! $stats = stats_get_remote_csv( $stats_csv_url ) ) {
+ $stats = stats_get_remote_csv( $stats_csv_url );
+ if ( ! $stats ) {
break;
}
@@ -1557,13 +1542,13 @@ function stats_get_csv( $table, $args = null ) {
* @return array
*/
function stats_get_remote_csv( $url ) {
- $method = 'GET';
+ $method = 'GET';
$timeout = 90;
- $user_id = JETPACK_MASTER_USER;
+ $user_id = 0; // Blog token.
- $get = Client::remote_request( compact( 'url', 'method', 'timeout', 'user_id' ) );
+ $get = Client::remote_request( compact( 'url', 'method', 'timeout', 'user_id' ) );
$get_code = wp_remote_retrieve_response_code( $get );
- if ( is_wp_error( $get ) || ( 2 !== intval( $get_code / 100 ) && 304 !== $get_code ) || empty( $get['body'] ) ) {
+ if ( is_wp_error( $get ) || ( 2 !== (int) ( $get_code / 100 ) && 304 !== $get_code ) || empty( $get['body'] ) ) {
return array(); // @todo: return an error?
} else {
return stats_str_getcsv( $get['body'] );
@@ -1571,31 +1556,16 @@ function stats_get_remote_csv( $url ) {
}
/**
- * Rather than parsing the csv and its special cases, we create a new file and do fgetcsv on it.
+ * Recursively run str_getcsv on the stats csv.
+ *
+ * @since 9.7.0 Remove custom handling since str_getcsv is available on all servers running this now.
*
- * @access public
* @param mixed $csv CSV.
* @return array.
*/
function stats_str_getcsv( $csv ) {
- if ( function_exists( 'str_getcsv' ) ) {
- $lines = str_getcsv( $csv, "\n" ); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.str_getcsvFound
- return array_map( 'str_getcsv', $lines );
- }
- if ( ! $temp = tmpfile() ) { // The tmpfile() automatically unlinks.
- return false;
- }
-
- $data = array();
-
- fwrite( $temp, $csv, strlen( $csv ) );
- fseek( $temp, 0 );
- while ( false !== $row = fgetcsv( $temp, 2000 ) ) {
- $data[] = $row;
- }
- fclose( $temp );
-
- return $data;
+ $lines = str_getcsv( $csv, "\n" );
+ return array_map( 'str_getcsv', $lines );
}
/**
@@ -1622,7 +1592,7 @@ function stats_get_from_restapi( $args = array(), $resource = '' ) {
$endpoint = jetpack_stats_api_path( $resource );
$api_version = '1.1';
$args = wp_parse_args( $args, array() );
- $cache_key = md5( implode( '|', array( $endpoint, $api_version, serialize( $args ) ) ) );
+ $cache_key = md5( implode( '|', array( $endpoint, $api_version, wp_json_encode( $args ) ) ) );
$transient_name = "jetpack_restapi_stats_cache_{$cache_key}";
@@ -1631,7 +1601,7 @@ function stats_get_from_restapi( $args = array(), $resource = '' ) {
// Return or expire this key.
if ( $stats_cache ) {
$time = key( $stats_cache );
- $data = $stats_cache[ $time ]; // WP_Error or string (JSON encoded object)
+ $data = $stats_cache[ $time ]; // WP_Error or string (JSON encoded object).
if ( is_wp_error( $data ) ) {
return $data;
@@ -1643,14 +1613,14 @@ function stats_get_from_restapi( $args = array(), $resource = '' ) {
// Do the dirty work.
$response = Client::wpcom_json_api_request_as_blog( $endpoint, $api_version, $args );
if ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
- // WP_Error
+ // WP_Error.
$data = is_wp_error( $response ) ? $response : new WP_Error( 'stats_error' );
- // WP_Error
+ // WP_Error.
$return = $data;
} else {
- // string (JSON encoded object)
+ // string (JSON encoded object).
$data = wp_remote_retrieve_body( $response );
- // object (rare: null on JSON failure)
+ // object (rare: null on JSON failure).
$return = json_decode( $data );
}
@@ -1684,12 +1654,13 @@ function jetpack_stats_load_admin_css() {
*
* @return mixed
*/
-function jetpack_stats_post_table( $columns ) { // Adds a stats link on the edit posts page
- if ( ! current_user_can( 'view_stats' ) || ! Jetpack::is_user_connected() ) {
+function jetpack_stats_post_table( $columns ) {
+ // Adds a stats link on the edit posts page.
+ if ( ! current_user_can( 'view_stats' ) || ! ( new Connection_Manager( 'jetpack' ) )->is_user_connected() ) {
return $columns;
}
- // Array-Fu to add before comments
- $pos = array_search( 'comments', array_keys( $columns ) );
+ // Array-Fu to add before comments.
+ $pos = array_search( 'comments', array_keys( $columns ), true );
if ( ! is_int( $pos ) ) {
return $columns;
}
@@ -1710,16 +1681,22 @@ function jetpack_stats_post_table( $columns ) { // Adds a stats link on the edit
* @return mixed
*/
function jetpack_stats_post_table_cell( $column, $post_id ) {
- if ( 'stats' == $column ) {
- if ( 'publish' != get_post_status( $post_id ) ) {
+ if ( 'stats' === $column ) {
+ if ( 'publish' !== get_post_status( $post_id ) ) {
printf(
'<span aria-hidden="true">—</span><span class="screen-reader-text">%s</span>',
esc_html__( 'No stats', 'jetpack' )
);
} else {
+ $stats_post_url = Redirect::get_url(
+ 'calypso-stats-post',
+ array(
+ 'path' => $post_id,
+ )
+ );
printf(
'<a href="%s" title="%s" class="dashicons dashicons-chart-bar" target="_blank"></a>',
- esc_url( "https://wordpress.com/stats/post/$post_id/" . Jetpack::build_raw_urls( get_home_url() ) ),
+ esc_url( $stats_post_url ),
esc_html__( 'View stats for this post in WordPress.com', 'jetpack' )
);
}