Skip to content

Commit

Permalink
Blog Stats Block: Include Visitors Data (#35427)
Browse files Browse the repository at this point in the history
* Add changelog

* Blog Stats block: Include visitors data

* Remove unneeded class name

* Update projects/plugins/jetpack/extensions/blocks/blog-stats/blog-stats.php

* Try fix tests

* Fix translator comment

* Update translator string

* Fix comments again

---------

Co-authored-by: Jasper Kang <[email protected]>
  • Loading branch information
2 people authored and spsiddarthan committed Feb 15, 2024
1 parent e5a5479 commit dc72551
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public function get_blog_stats( $request ) {
( new WPCOM_Stats() )->get_stats( array( 'fields' => 'stats' ) )
);

if ( ! isset( $blog_data->stats->views ) ) {
if ( ! isset( $blog_data->stats->views ) || ! isset( $blog_data->stats->visitors ) ) {
return false;
}

Expand All @@ -72,8 +72,9 @@ public function get_blog_stats( $request ) {
}

return array(
'post-views' => $post_data->views,
'blog-views' => $blog_data->stats->views,
'post-views' => $post_data->views,
'blog-visitors' => $blog_data->stats->visitors,
'blog-views' => $blog_data->stats->views,
);
}
}
Expand Down
4 changes: 4 additions & 0 deletions projects/plugins/jetpack/changelog/add-blog-stats-visitors
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: enhancement

Blog Stats Block: allow displaying site's number of visitors.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"name": "jetpack/blog-stats",
"title": "Blog Stats",
"description": "Show a stats counter for your blog.",
"keywords": [ "views", "hits", "analytics", "counter" ],
"keywords": [ "views", "hits", "analytics", "counter", "visitors" ],
"version": "1.0",
"textdomain": "jetpack",
"category": "grow",
Expand All @@ -31,6 +31,10 @@
"label": {
"type": "string"
},
"statsData": {
"type": "string",
"default": "views"
},
"statsOption": {
"type": "string",
"default": "site"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ function register_block() {
function load_assets( $attributes ) {
Jetpack_Gutenberg::load_assets_as_required( __DIR__ );

$views = 0;
$stats = 0;

// For when there's no post ID - eg. search pages.
if ( $attributes['statsOption'] === 'post' && ! get_the_ID() ) {
Expand All @@ -71,36 +71,40 @@ function load_assets( $attributes ) {
);

if ( isset( $data->views ) ) {
$views = $data->views;
$stats = $data->views;
}
} else {
$data = convert_stats_array_to_object(
( new WPCOM_Stats() )->get_stats( array( 'fields' => 'stats' ) )
);

if ( isset( $data->stats->views ) ) {
$views = $data->stats->views;
if ( $attributes['statsData'] === 'views' && isset( $data->stats->views ) ) {
$stats = $data->stats->views;
}

if ( $attributes['statsData'] === 'visitors' && isset( $data->stats->visitors ) ) {
$stats = $data->stats->visitors;
}
}

$label = $attributes['label'] ? $attributes['label'] : esc_html(
$fallback_label = $attributes['statsData'] === 'visitors' ? esc_html(
/* Translators: Number of visitors */
_n( 'visitor', 'visitors', $stats, 'jetpack' )
) : esc_html(
/* Translators: Number of views */
_n(
'hit',
'hits',
$views,
'jetpack'
)
_n( 'hit', 'hits', $stats, 'jetpack' )
);

$label = $attributes['label'] ? $attributes['label'] : $fallback_label;

$wrapper_attributes = \WP_Block_Supports::get_instance()->apply_block_supports();

return sprintf(
'<div class="jetpack-blog-stats%s%s"%s><p>%s %s</p></div>',
! empty( $attributes['className'] ) ? ' ' . esc_attr( $attributes['className'] ) : '',
! empty( $wrapper_attributes['class'] ) ? ' ' . esc_attr( $wrapper_attributes['class'] ) : '',
! empty( $wrapper_attributes['style'] ) ? ' style="' . esc_attr( $wrapper_attributes['style'] ) . '"' : '',
esc_html( number_format_i18n( $views ) ),
esc_html( number_format_i18n( $stats ) ),
wp_kses_post( $label )
);
}
33 changes: 30 additions & 3 deletions projects/plugins/jetpack/extensions/blocks/blog-stats/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@ import { PanelBody, RadioControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

export function BlogStatsInspectorControls( { attributes, setAttributes } ) {
const { statsOption } = attributes;
const { statsData, statsOption } = attributes;

const RADIO_OPTIONS = [
const STATS_DATA_RADIO = [
{
value: 'views',
label: __( 'Views', 'jetpack' ),
},
{
value: 'visitors',
label: __( 'Visitors', 'jetpack' ),
},
];

const STATS_OPTION_RADIO = [
{
value: 'site',
label: __( 'My whole site', 'jetpack' ),
Expand All @@ -18,11 +29,27 @@ export function BlogStatsInspectorControls( { attributes, setAttributes } ) {
return (
<>
<PanelBody title={ __( 'Settings', 'jetpack' ) }>
<RadioControl
label={ __( 'Views or visitors', 'jetpack' ) }
selected={ statsData }
onChange={ value => setAttributes( { statsData: value } ) }
options={ STATS_DATA_RADIO }
help={ __(
'Views represent site visits, whereas visitors represent unique individuals.',
'jetpack'
) }
/>
<RadioControl
label={ __( 'Show stats data for', 'jetpack' ) }
selected={ statsOption }
onChange={ value => setAttributes( { statsOption: value } ) }
options={ RADIO_OPTIONS }
options={ STATS_OPTION_RADIO }
disabled={ statsData === 'visitors' }
help={
statsData === 'visitors'
? __( "Visitor counts aren't available for individual posts.", 'jetpack' )
: null
}
/>
<span className="jetpack-blog-stats__delay-notice">
{ __( 'Stats are delayed for up to 5 minutes.', 'jetpack' ) }
Expand Down
30 changes: 23 additions & 7 deletions projects/plugins/jetpack/extensions/blocks/blog-stats/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ import { InactiveStatsPlaceholder } from './inactive-placeholder';
function BlogStatsEdit( { attributes, className, setAttributes } ) {
const { isLoadingModules, isChangingStatus, isModuleActive, changeStatus } =
useModuleStatus( 'stats' );
const { label, statsOption } = attributes;
const { label, statsData, statsOption } = attributes;
const [ blogViews, setBlogViews ] = useState( null );
const [ blogVisitors, setBlogVisitors ] = useState();
const [ postViews, setPostViews ] = useState();
const views = statsOption === 'post' ? postViews : blogViews;

const blogStats = statsData === 'views' ? blogViews : blogVisitors;
const stats = statsOption === 'post' ? postViews : blogStats;

const postId = useSelect( select => select( 'core/editor' ).getCurrentPostId(), [] );

Expand All @@ -26,6 +29,7 @@ function BlogStatsEdit( { attributes, className, setAttributes } ) {
: '/wpcom/v2/blog-stats',
} ).then( response => {
setBlogViews( response[ 'blog-views' ] );
setBlogVisitors( response[ 'blog-visitors' ] );

// Display "12,345" as an obvious placeholder when we have no Post ID.
// Applies to widgets, FSE templates etc.
Expand All @@ -34,6 +38,13 @@ function BlogStatsEdit( { attributes, className, setAttributes } ) {
}
}, [ postId, isModuleActive ] );

// We don't collect visitor data for individual posts.
useEffect( () => {
if ( statsData === 'visitors' ) {
setAttributes( { statsOption: 'site' } );
}
}, [ statsData, setAttributes ] );

if ( ! isModuleActive && ! isLoadingModules ) {
return (
<InactiveStatsPlaceholder
Expand All @@ -44,6 +55,14 @@ function BlogStatsEdit( { attributes, className, setAttributes } ) {
);
}

const visitorsPlaceholder =
/* Translators: Number of visitors */
_n( 'visitor', 'visitors', parseInt( stats ), 'jetpack', 0 );

const viewsPlaceholder =
/* Translators: Number of views */
_n( 'hit', 'hits', parseInt( stats ), 'jetpack', 0 );

return (
<>
<InspectorControls>
Expand All @@ -55,13 +74,10 @@ function BlogStatsEdit( { attributes, className, setAttributes } ) {
<p className="jetpack-blog-stats__loading">{ __( 'Loading stats…', 'jetpack' ) }</p>
) : (
<p>
<span>{ numberFormat( views ) } </span>
<span>{ numberFormat( stats ) } </span>
<RichText
tagName="span"
placeholder={
/* Translators: Number of views */
_n( 'hit', 'hits', parseInt( views ), 'jetpack' )
}
placeholder={ statsData === 'visitors' ? visitorsPlaceholder : viewsPlaceholder }
value={ label }
allowedFormats={ [ 'core/bold', 'core/italic', 'core/link' ] }
onChange={ newLabel => setAttributes( { label: newLabel } ) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
@import '@automattic/jetpack-base-styles/gutenberg-base-styles';

.wp-block-jetpack-blog-stats {
.jetpack-blog-stats__loading {
// Same as RichText component's placeholder opacity from Core.
Expand All @@ -12,5 +10,5 @@
}

.jetpack-blog-stats__delay-notice {
color: $gray-700;
font-size: 12px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { BlogStatsInspectorControls } from '../controls';
describe( 'BlogStatsControls', () => {
const defaultAttributes = {
label: 'hits',
statsData: 'views',
statsOption: 'site',
};

Expand All @@ -19,10 +20,30 @@ describe( 'BlogStatsControls', () => {
} );

describe( 'Inspector settings', () => {
test( 'loads and displays settings', () => {
test( 'loads and displays views or visitors settings', () => {
render( <BlogStatsInspectorControls { ...defaultProps } /> );

expect( screen.getByLabelText( 'Views' ) ).toBeInTheDocument();
expect( screen.getByLabelText( 'Visitors' ) ).toBeInTheDocument();
} );

test( 'defaults stats data to views', () => {
render( <BlogStatsInspectorControls { ...defaultProps } /> );

expect( screen.getByLabelText( 'Views' ) ).toBeChecked();
} );

test( 'sets the statsData attribute', async () => {
const user = userEvent.setup();
render( <BlogStatsInspectorControls { ...defaultProps } /> );
await user.click( screen.getByLabelText( 'Visitors' ) );

expect( setAttributes ).toHaveBeenCalledWith( { statsData: 'visitors' } );
} );

test( 'loads and displays option settings', () => {
render( <BlogStatsInspectorControls { ...defaultProps } /> );

expect( screen.getByText( 'Settings' ) ).toBeInTheDocument();
expect( screen.getByLabelText( 'My whole site' ) ).toBeInTheDocument();
expect( screen.getByLabelText( 'This individual post' ) ).toBeInTheDocument();
} );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"name": "jetpack/blog-stats",
"isValid": true,
"attributes": {
"statsData": "views",
"statsOption": "site"
},
"innerBlocks": [],
Expand Down

0 comments on commit dc72551

Please sign in to comment.