Skip to content

Commit

Permalink
Add Google Analytics module (#5603)
Browse files Browse the repository at this point in the history
* Adds Google Analytics support using the wp-google-analytics plugin

* Updates sort order of google analytics plugin

* Adds pro detection and solves sync issue

* Makes form legend translatable.

* Updates module description

* Updates module coding style and removes business check function

* PR Feedback

* Adds Jetpack support link

* Fixes broken tests

* Fixes the Business plan checks and removes unnecessary code

* Adds Google Analytics JS to the js:hint task exception list

* Pointing help back to Google Analytics article on WordPress.com

* Maintains compatibility with WordPress.com option name.

* Translates the jetpack option name to the WordPress.com name when getting site settings.

* Makes form placeholder translatable

* Reverts snafu with translatable string on the Verification Tools component.

* Updates upgrade button with new Jetpack redirect address

* Removes unused constant.

* Adds Google Analytics to the PRO list on the search page.

* Removes the paywall from the module, adding it to the deactivation list.

* Adds Google Analytics to the Plans page

* Updates the Google Analytics module heading

* Fixes the Google Analytics module appearance when searching

* Removes tokens for custom variables since they are not supported on WordPress.com

* Removes backward compatibility code since it's not needed with this new plugin

* Removed code for logging outgoing links since it's not supported on WordPress.com

* Adds Jetpack monthly checks to the pro status component

* Removes broken link from the Google Analytics module description

* Removes unused callback functions

* Google Analytics code generation function simplified to use only tracking code option

* Refactors the get options function to retrieve and validate only the tracking code

* Removes whitespace

* Removes unused variables

* Changes class name to compy with WordPress coding guidelines

* Removes extra tab

* Fixes Google Analytics upgrade url

* Removes extra call to isModuleActivated

* Removes Google Analytics link from module description

* Removes the settings form in favor of a link pointing to WordPress.com

* Removes upgrade button flash for Google Analytics

* Moves the Google Analytics module to the top with the rest of the paid modules

* Changes the way we import from loadash

* Fix undefined  && update support link
  • Loading branch information
rodrigoi authored and dereksmart committed Jan 31, 2017
1 parent 0fe1b5f commit cfc5267
Show file tree
Hide file tree
Showing 16 changed files with 349 additions and 36 deletions.
14 changes: 14 additions & 0 deletions _inc/client/components/module-settings/modules-per-tab-page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,20 @@ const AllModuleSettingsComponent = React.createClass( {
return ( <SitemapsSettings module={ module } { ...this.props } /> );
case 'wordads':
return ( <WordAdsSettings module={ module } /> );
case 'google-analytics':
if ( 'inactive' === module.configure_url ) {
return (
<div>
{ __( 'Activate this module to use Google Analytics.' ) }
</div>
);
} else {
return (
<div>
<ExternalLink className="jp-module-settings__external-link" icon={ true } iconSize={ 16 } href={ module.configure_url }>{ __( 'Configure Google Analytics settings.' ) }</ExternalLink>
</div>
);
}
case 'gravatar-hovercards':
case 'contact-form':
case 'latex':
Expand Down
14 changes: 13 additions & 1 deletion _inc/client/engagement/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export const Engagement = ( props ) => {
let cards = [
[ 'seo-tools', getModule( 'seo-tools' ).name, getModule( 'seo-tools' ).description, getModule( 'seo-tools' ).learn_more_button ],
[ 'wordads', getModule( 'wordads' ).name, getModule( 'wordads' ).description, getModule( 'wordads' ).learn_more_button ],
[ 'google-analytics', getModule( 'google-analytics' ).name, getModule( 'google-analytics' ).description, getModule( 'google-analytics' ).learn_more_button ],
[ 'stats', getModule( 'stats' ).name, getModule( 'stats' ).description, getModule( 'stats' ).learn_more_button ],
[ 'sharedaddy', getModule( 'sharedaddy' ).name, getModule( 'sharedaddy' ).description, getModule( 'sharedaddy' ).learn_more_button ],
[ 'publicize', getModule( 'publicize' ).name, getModule( 'publicize' ).description, getModule( 'publicize' ).learn_more_button ],
Expand Down Expand Up @@ -100,7 +101,7 @@ export const Engagement = ( props ) => {
customClasses = unavailableInDevMode ? 'devmode-disabled' : '',
toggle = '',
adminAndNonAdmin = isAdmin || includes( nonAdminAvailable, element[0] ),
isPro = 'seo-tools' === element[0] || 'wordads' === element[0],
isPro = includes( [ 'seo-tools', 'wordads', 'google-analytics' ], element[0] ),
proProps = {
module: element[0],
configure_url: ''
Expand All @@ -127,6 +128,7 @@ export const Engagement = ( props ) => {
toggle = __( 'Unavailable in Dev Mode' );
} else if ( isAdmin ) {
if ( ( 'seo-tools' === element[0] && ! hasBusiness ) ||
( 'google-analytics' === element[0] && ! hasBusiness ) ||
( 'wordads' === element[0] && ! hasPremiumOrBusiness ) ) {
toggle = <ProStatus proFeature={ element[0] } />;
} else {
Expand All @@ -143,6 +145,10 @@ export const Engagement = ( props ) => {
}
}

if ( element[0] === 'google-analytics' && ! hasBusiness ) {
isModuleActive = false;
}

if ( isPro ) {
// Add a "pro" button next to the header title
element[1] =
Expand Down Expand Up @@ -172,6 +178,12 @@ export const Engagement = ( props ) => {
: 'inactive';
}

moduleDescription = <AllModuleSettings module={ proProps } />;
} else if ( element[0] === 'google-analytics' ) {
proProps.configure_url = isModuleActive
? 'https://wordpress.com/settings/analytics/' + props.siteRawUrl
: 'inactive';

moduleDescription = <AllModuleSettings module={ proProps } />;
}

Expand Down
34 changes: 30 additions & 4 deletions _inc/client/plans/plan-body.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ const PlanBody = React.createClass( {
render() {
let planCard = '';
switch ( this.props.plan ) {
case 'jetpack_personal':
case 'jetpack_personal_monthly':
case 'jetpack_premium':
case 'jetpack_premium_monthly':
case 'jetpack_personal':
case 'jetpack_personal_monthly':
case 'jetpack_premium':
case 'jetpack_premium_monthly':
case 'jetpack_business':
case 'jetpack_business_monthly':
planCard = (
Expand Down Expand Up @@ -226,6 +226,32 @@ const PlanBody = React.createClass( {
: ''
}

{
includes( [ 'jetpack_business', 'jetpack_business_monthly' ], this.props.plan ) ?
<div className="jp-landing__plan-features-card">
<h3 className="jp-landing__plan-features-title">{ __( 'Google Analytics' ) }</h3>
<p>{ __( 'Track website statistics with Google Analytics for a deeper understanding of your website visitors and customers.' ) }</p>
{
this.props.isFetchingPluginsData ? '' :
this.props.isModuleActivated( 'google-analytics' ) ? (
<Button href={ 'https://wordpress.com/settings/analytics/' + this.props.siteRawUrl } className="is-primary">
{ __( 'Configure Google Analytics' ) }
</Button>
)
: (
<Button
onClick={ this.props.activateModule.bind( null, 'google-analytics' ) }
className="is-primary"
disabled={ this.props.isActivatingModule( 'google-analytics' ) }
>
{ __( 'Activate Google Analytics' ) }
</Button>
)
}
</div>
: ''
}

{
includes( [ 'jetpack_personal', 'jetpack_personal_monthly' ], this.props.plan ) ?
<div className="jp-landing__plan-features-card">
Expand Down
17 changes: 17 additions & 0 deletions _inc/client/pro-status/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import React from 'react';
import { connect } from 'react-redux';
import { translate as __ } from 'i18n-calypso';
import { includes } from 'lodash';
import Button from 'components/button';
import SimpleNotice from 'components/notice';

Expand Down Expand Up @@ -121,6 +122,22 @@ const ProStatus = React.createClass( {
);
}

if ( 'google-analytics' === feature && ! includes( [ 'jetpack_business', 'jetpack_business_monthly' ], sitePlan.product_slug ) ) {
if ( this.props.fetchingSiteData ) {
return '';
}

return (
<Button
compact={ true }
primary={ true }
href={ 'https://jetpack.com/redirect/?source=upgrade-google-analytics&site=' + this.props.siteRawUrl + '&feature=google-analytics' }
>
{ __( 'Upgrade' ) }
</Button>
);
}

if ( sitePlan.product_slug ) {
let btnVals = {};
if ( 'jetpack_free' !== sitePlan.product_slug ) {
Expand Down
21 changes: 12 additions & 9 deletions _inc/client/search/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { connect } from 'react-redux';
import FoldableCard from 'components/foldable-card';
import { ModuleToggle } from 'components/module-toggle';
import forEach from 'lodash/forEach';
import includes from 'lodash/includes';
import Button from 'components/button';
import Gridicon from 'components/gridicon';
import Collection from 'components/search/search-collection.jsx';
Expand Down Expand Up @@ -105,24 +106,22 @@ export const SearchResults = ( {
}

cards = moduleList.map( ( element ) => {
let isPro = 'scan' === element[0]
|| 'akismet' === element[0]
|| 'backups' === element[0]
|| 'seo-tools' === element[0],
proProps = {},
const isPro = includes( [ 'scan', 'akismet', 'backups', 'seo-tools', 'google-analytics' ], element[0] );
let proProps = {},
isModuleActive = isModuleActivated( element[0] ),
unavailableDevMode = unavailableInDevMode( element[0] ),
toggle = unavailableDevMode ? __( 'Unavailable in Dev Mode' ) : (
<ModuleToggle
slug={ element[0] }
activated={ isModuleActivated( element[0] ) }
activated={ isModuleActive }
toggling={ isTogglingModule( element[0] ) }
toggleModule={ toggleModule }
/>
),
customClasses = unavailableDevMode ? 'devmode-disabled' : '',
wordAdsSubHeader = element[2];

if ( 'wordads' === element[0] && ! isModuleActivated( element[0] ) ) {
if ( 'wordads' === element[0] && ! isModuleActive ) {
wordAdsSubHeader = <WordAdsSubHeaderTos subheader={ element[2] } />
}

Expand All @@ -132,13 +131,17 @@ export const SearchResults = ( {
configure_url: ''
};

if (
if ( (
'videopress' !== element[0]
||
'seo-tools' !== element[0]
|| (
'seo-tools' === element[0]
&& ! hasBusiness
) )
&& (
'google-analytics' !== element[0]
|| ( 'google-analytics' === element[0] && ! hasBusiness )
)
) {
toggle = <ProStatus proFeature={ element[0] } siteAdminUrl={ siteAdminUrl } />;
Expand Down Expand Up @@ -199,7 +202,7 @@ export const SearchResults = ( {
) }
>
{
isModuleActivated( element[0] ) || isPro ?
isModuleActive || isPro ?
<AllModuleSettings module={ isPro ? proProps : getModule( element[0] ) } /> :
// Render the long_description if module is deactivated
<div dangerouslySetInnerHTML={ renderLongDescription( getModule( element[0] ) ) } />
Expand Down
6 changes: 3 additions & 3 deletions _inc/lib/admin-pages/class.jetpack-admin-page.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,15 +216,15 @@ function check_plan_deactivate_modules( $page ) {
$active = Jetpack::get_active_modules();
switch ( $current->plan->product_slug ) {
case 'jetpack_free':
$to_deactivate = array( 'seo-tools', 'videopress' );
$to_deactivate = array( 'seo-tools', 'videopress', 'google-analytics' );
break;
case 'jetpack_personal':
case 'jetpack_personal_monthly':
$to_deactivate = array( 'seo-tools', 'videopress' );
$to_deactivate = array( 'seo-tools', 'videopress', 'google-analytics' );
break;
case 'jetpack_premium':
case 'jetpack_premium_monthly':
$to_deactivate = array( 'seo-tools' );
$to_deactivate = array( 'seo-tools', 'google-analytics' );
break;
}
$to_deactivate = array_intersect( $active, $to_deactivate );
Expand Down
19 changes: 19 additions & 0 deletions _inc/lib/class.core-rest-api-endpoints.php
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,16 @@ public static function get_updateable_data_list( $selector = '' ) {
'validate_callback' => __CLASS__ . '::validate_boolean',
'jp_group' => 'wordads',
),

// Google Analytics
'google_analytics_tracking_id' => array(
'description' => esc_html__( 'Google Analytics', 'jetpack' ),
'type' => 'string',
'default' => '',
'validate_callback' => __CLASS__ . '::validate_alphanum',
'jp_group' => 'google-analytics',
),

// Stats
'admin_bar' => array(
'description' => esc_html__( 'Put a chart showing 48 hours of views in the admin bar.', 'jetpack' ),
Expand Down Expand Up @@ -2094,6 +2104,15 @@ public static function prepare_options_for_response( $module = '' ) {
$options = self::split_options( $options, get_option( 'verification_services_codes' ) );
break;

case 'google-analytics':
$wga = get_option( 'jetpack_wga' );
$code = '';
if ( is_array( $wga ) && array_key_exists( 'code', $wga ) ) {
$code = $wga[ 'code' ];
}
$options[ 'google_analytics_tracking_id' ][ 'current_value' ] = $code;
break;

case 'sharedaddy':
// It's local, but it must be broken apart since it's saved as an array.
if ( ! class_exists( 'Sharing_Service' ) && ! @include( JETPACK__PLUGIN_DIR . 'modules/sharedaddy/sharing-service.php' ) ) {
Expand Down
8 changes: 8 additions & 0 deletions _inc/lib/core-api/class.jetpack-core-api-module-endpoints.php
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,14 @@ public function update_data( $data ) {
$updated = get_option( $option ) != $value ? update_option( $option, (bool) $value ? 'letitsnow' : '' ) : true;
break;

case 'google_analytics_tracking_id':
$grouped_options = $grouped_options_current = (array) get_option( 'jetpack_wga' );
$grouped_options[ 'code' ] = $value;

// If option value was the same, consider it done.
$updated = $grouped_options_current != $grouped_options ? update_option( 'jetpack_wga', $grouped_options ) : true;
break;

case 'wp_mobile_featured_images':
case 'wp_mobile_excerpt':
$value = ( 'enabled' === $value ) ? '1' : '0';
Expand Down
11 changes: 6 additions & 5 deletions class.jetpack.php
Original file line number Diff line number Diff line change
Expand Up @@ -1217,14 +1217,14 @@ public static function get_active_plan() {

// Set the default options
if ( ! $plan ) {
$plan = array(
'product_slug' => 'jetpack_free',
'supports' => array(),
$plan = array(
'product_slug' => 'jetpack_free',
'supports' => array(),
);
}

// Define what paid modules are supported by personal plans
$personal_plans = array(
$personal_plans = array(
'jetpack_personal',
'jetpack_personal_monthly',
);
Expand Down Expand Up @@ -1261,6 +1261,7 @@ public static function get_active_plan() {
'akismet',
'vaultpress',
'seo-tools',
'google-analytics',
);
}

Expand Down Expand Up @@ -2292,7 +2293,7 @@ public static function get_translated_modules( $modules ) {
*/
public static function get_active_modules() {
$active = Jetpack_Options::get_option( 'active_modules' );

if ( ! is_array( $active ) ) {
$active = array();
}
Expand Down
23 changes: 17 additions & 6 deletions json-endpoints/class.wpcom-json-api-site-settings-endpoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ public function get_settings_response() {
'moderation_keys' => get_option( 'moderation_keys' ),
'blacklist_keys' => get_option( 'blacklist_keys' ),
'lang_id' => get_option( 'lang_id' ),
'wga' => get_option( 'wga' ),
'wga' => $this->get_google_analytics(),
'disabled_likes' => (bool) get_option( 'disabled_likes' ),
'disabled_reblogs' => (bool) get_option( 'disabled_reblogs' ),
'jetpack_comment_likes_enabled' => (bool) get_option( 'jetpack_comment_likes_enabled', false ),
Expand Down Expand Up @@ -266,6 +266,10 @@ protected function get_locale( $key ) {
return false;
}

protected function get_google_analytics () {
$option_name = defined( 'IS_WPCOM' ) && IS_WPCOM ? 'wga' : 'jetpack_wga';
return get_option( $option_name );
}

/**
* Updates site settings for authorized users
Expand Down Expand Up @@ -352,12 +356,18 @@ public function update_settings() {
}
break;
case 'wga':
case 'jetpack_wga':
if ( ! isset( $value['code'] ) || ! preg_match( '/^$|^UA-[\d-]+$/i', $value['code'] ) ) {
return new WP_Error( 'invalid_code', 'Invalid UA ID' );
}
$wga = get_option( 'wga', array() );

$is_wpcom = defined( 'IS_WPCOM' ) && IS_WPCOM;
$option_name = $is_wpcom ? 'wga' : 'jetpack_wga';

$wga = get_option( $option_name, array() );
$wga['code'] = $value['code']; // maintain compatibility with wp-google-analytics
if ( update_option( 'wga', $wga ) ) {

if ( update_option( $option_name, $wga ) ) {
$updated[ $key ] = $value;
}

Expand All @@ -366,10 +376,11 @@ public function update_settings() {
/** This action is documented in modules/widgets/social-media-icons.php */
do_action( 'jetpack_bump_stats_extras', 'google-analytics', $enabled_or_disabled );

$business_plugins = WPCOM_Business_Plugins::instance();
$business_plugins->activate_plugin( 'wp-google-analytics' );
if ( $is_wpcom ) {
$business_plugins = WPCOM_Business_Plugins::instance();
$business_plugins->activate_plugin( 'wp-google-analytics' );
}
break;

case 'jetpack_testimonial':
case 'jetpack_portfolio':
case 'jetpack_comment_likes_enabled':
Expand Down
14 changes: 14 additions & 0 deletions modules/google-analytics.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

/**
* Module Name: Google Analytics
* Module Description: Lets you use Google Analytics to track your WordPress site statistics.
* First Introduced: 4.5
* Sort Order: 37
* Requires Connection: Yes
* Auto Activate: No
* Feature: Engagement
* Additional Search Queries: webmaster, google, analytics, console
*/

include dirname( __FILE__ ) . "/google-analytics/wp-google-analytics.php";
Loading

0 comments on commit cfc5267

Please sign in to comment.