Skip to content

Commit

Permalink
Merge branch 'master' of github.com:Automattic/jetpack into e2e-separ…
Browse files Browse the repository at this point in the history
…ate-node-project
  • Loading branch information
adimoldovan committed Feb 16, 2021
2 parents a4d8ee0 + ba81f2c commit 3e87c6b
Show file tree
Hide file tree
Showing 65 changed files with 1,724 additions and 444 deletions.
3 changes: 3 additions & 0 deletions projects/packages/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## Ignore composer.lock and vendor folders for our library packages
/**/composer.lock
/**/vendor/

## Test package added through unit testing. Maybe temporary.
/test/
55 changes: 28 additions & 27 deletions projects/packages/options/legacy/class-jetpack-options.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,33 +89,34 @@ public static function get_option_names( $type = 'compact' ) {
}

return array(
'id', // (int) The Client ID/WP.com Blog ID of this site.
'publicize_connections', // (array) An array of Publicize connections from WordPress.com.
'master_user', // (int) The local User ID of the user who connected this site to jetpack.wordpress.com.
'version', // (string) Used during upgrade procedure to auto-activate new modules. version:time.
'old_version', // (string) Used to determine which modules are the most recently added. previous_version:time.
'fallback_no_verify_ssl_certs', // (int) Flag for determining if this host must skip SSL Certificate verification due to misconfigured SSL.
'time_diff', // (int) Offset between Jetpack server's clocks and this server's clocks. Jetpack Server Time = time() + (int) Jetpack_Options::get_option( 'time_diff' )
'public', // (int|bool) If we think this site is public or not (1, 0), false if we haven't yet tried to figure it out.
'videopress', // (array) VideoPress options array.
'is_network_site', // (int|bool) If we think this site is a network or a single blog (1, 0), false if we haven't yet tried to figue it out.
'social_links', // (array) The specified links for each social networking site.
'identity_crisis_whitelist', // (array) An array of options, each having an array of the values whitelisted for it.
'gplus_authors', // (array) The Google+ authorship information for connected users.
'last_heartbeat', // (int) The timestamp of the last heartbeat that fired.
'hide_jitm', // (array) A list of just in time messages that we should not show because they have been dismissed by the user.
'custom_css_4.7_migration', // (bool) Whether Custom CSS has scanned for and migrated any legacy CSS CPT entries to the new Core format.
'image_widget_migration', // (bool) Whether any legacy Image Widgets have been converted to the new Core widget.
'gallery_widget_migration', // (bool) Whether any legacy Gallery Widgets have been converted to the new Core widget.
'sso_first_login', // (bool) Is this the first time the user logins via SSO.
'dismissed_hints', // (array) Part of Plugin Search Hints. List of cards that have been dismissed.
'first_admin_view', // (bool) Set to true the first time the user views the admin. Usually after the initial connection.
'setup_wizard_questionnaire', // (array) (DEPRECATED) List of user choices from the setup wizard.
'setup_wizard_status', // (string) (DEPRECATED) Status of the setup wizard.
'licensing_error', // (string) Last error message occurred while attaching licenses that is yet to be surfaced to the user.
'recommendations_banner_enabled', // (bool) Whether the recommendations are enabled or not.
'recommendations_data', // (array) The user choice and other data for the recommendations.
'recommendations_step', // (string) The current step of the recommendations.
'id', // (int) The Client ID/WP.com Blog ID of this site.
'publicize_connections', // (array) An array of Publicize connections from WordPress.com.
'master_user', // (int) The local User ID of the user who connected this site to jetpack.wordpress.com.
'version', // (string) Used during upgrade procedure to auto-activate new modules. version:time.
'old_version', // (string) Used to determine which modules are the most recently added. previous_version:time.
'fallback_no_verify_ssl_certs', // (int) Flag for determining if this host must skip SSL Certificate verification due to misconfigured SSL.
'time_diff', // (int) Offset between Jetpack server's clocks and this server's clocks. Jetpack Server Time = time() + (int) Jetpack_Options::get_option( 'time_diff' )
'public', // (int|bool) If we think this site is public or not (1, 0), false if we haven't yet tried to figure it out.
'videopress', // (array) VideoPress options array.
'is_network_site', // (int|bool) If we think this site is a network or a single blog (1, 0), false if we haven't yet tried to figue it out.
'social_links', // (array) The specified links for each social networking site.
'identity_crisis_whitelist', // (array) An array of options, each having an array of the values whitelisted for it.
'gplus_authors', // (array) The Google+ authorship information for connected users.
'last_heartbeat', // (int) The timestamp of the last heartbeat that fired.
'hide_jitm', // (array) A list of just in time messages that we should not show because they have been dismissed by the user.
'custom_css_4.7_migration', // (bool) Whether Custom CSS has scanned for and migrated any legacy CSS CPT entries to the new Core format.
'image_widget_migration', // (bool) Whether any legacy Image Widgets have been converted to the new Core widget.
'gallery_widget_migration', // (bool) Whether any legacy Gallery Widgets have been converted to the new Core widget.
'sso_first_login', // (bool) Is this the first time the user logins via SSO.
'dismissed_hints', // (array) Part of Plugin Search Hints. List of cards that have been dismissed.
'first_admin_view', // (bool) Set to true the first time the user views the admin. Usually after the initial connection.
'setup_wizard_questionnaire', // (array) (DEPRECATED) List of user choices from the setup wizard.
'setup_wizard_status', // (string) (DEPRECATED) Status of the setup wizard.
'licensing_error', // (string) Last error message occurred while attaching licenses that is yet to be surfaced to the user.
'recommendations_banner_dismissed', // (bool) Determines if the recommendations dashboard banner is dismissed or not.
'recommendations_banner_enabled', // (bool) Whether the recommendations are enabled or not.
'recommendations_data', // (array) The user choice and other data for the recommendations.
'recommendations_step', // (string) The current step of the recommendations.
);
}

Expand Down
19 changes: 1 addition & 18 deletions projects/packages/sync/src/class-defaults.php
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,6 @@ public static function get_constants_whitelist() {
'main_network_site_wpcom_id' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'main_network_site_wpcom_id' ),
'site_url' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'site_url' ),
'home_url' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'home_url' ),
'single_user_site' => array( 'Jetpack', 'is_single_user_site' ),
'updates' => array( 'Jetpack', 'get_updates' ),
'has_file_system_write_access' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'file_system_write_access' ),
'is_version_controlled' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'is_version_controlled' ),
'taxonomies' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_taxonomies' ),
Expand All @@ -296,13 +294,11 @@ public static function get_constants_whitelist() {
'wp_version' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'wp_version' ),
'get_plugins' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_plugins' ),
'get_plugins_action_links' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_plugins_action_links' ),
'active_modules' => array( 'Jetpack', 'get_active_modules' ),
'hosting_provider' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_hosting_provider' ),
'locale' => 'get_locale',
'site_icon_url' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'site_icon_url' ),
'roles' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'roles' ),
'timezone' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_timezone' ),
'available_jetpack_blocks' => array( 'Jetpack_Gutenberg', 'get_availability' ), // Includes both Gutenberg blocks *and* plugins.
'paused_themes' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_paused_themes' ),
'paused_plugins' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_paused_plugins' ),
'theme_support' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_theme_support' ),
Expand Down Expand Up @@ -352,19 +348,6 @@ public static function get_constants_whitelist() {
* @return array Whitelist of callables allowed to be managed via the JSON API.
*/
public static function get_callable_whitelist() {
$default = self::$default_callable_whitelist;

if ( defined( 'JETPACK__PLUGIN_DIR' ) && include_once JETPACK__PLUGIN_DIR . 'modules/sso/class.jetpack-sso-helpers.php' ) {
$sso_helpers = array(
'sso_is_two_step_required' => array( 'Jetpack_SSO_Helpers', 'is_two_step_required' ),
'sso_should_hide_login_form' => array( 'Jetpack_SSO_Helpers', 'should_hide_login_form' ),
'sso_match_by_email' => array( 'Jetpack_SSO_Helpers', 'match_by_email' ),
'sso_new_user_override' => array( 'Jetpack_SSO_Helpers', 'new_user_override' ),
'sso_bypass_default_login_form' => array( 'Jetpack_SSO_Helpers', 'bypass_login_forward_wpcom' ),
);
$default = array_merge( $default, $sso_helpers );
}

/**
* Filter the list of callables that are manageable via the JSON API.
*
Expand All @@ -374,7 +357,7 @@ public static function get_callable_whitelist() {
*
* @param array The default list of callables.
*/
return apply_filters( 'jetpack_sync_callable_whitelist', $default );
return apply_filters( 'jetpack_sync_callable_whitelist', self::$default_callable_whitelist );
}

/**
Expand Down
8 changes: 6 additions & 2 deletions projects/packages/sync/src/modules/class-callables.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,10 +226,14 @@ public function get_all_callables() {
* @access private
*
* @param callable $callable Callable to invoke.
* @return mixed Return value of the callable.
* @return mixed Return value of the callable, null if not callable.
*/
private function get_callable( $callable ) {
return call_user_func( $callable );
if ( is_callable( $callable ) ) {
return call_user_func( $callable );
} else {
return null;
}
}

/**
Expand Down
67 changes: 37 additions & 30 deletions projects/plugins/jetpack/_inc/client/recommendations/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ import QueryRecommendationsUpsell from 'components/data/query-recommendations-up
import QueryRewindStatus from 'components/data/query-rewind-status';
import QuerySite from 'components/data/query-site';
import QuerySitePlugins from 'components/data/query-site-plugins';
import { getStep } from 'state/recommendations';
import { getStep, isRecommendationsDataLoaded } from 'state/recommendations';
import { LoadingCard } from './sidebar/loading-card';

const RecommendationsComponent = props => {
const { step } = props;
const { isLoading, step } = props;

let redirectPath;
switch ( step ) {
case 'not-started':
case 'site-type-question':
case 'setup-wizard-completed':
redirectPath = '/site-type';
break;
case 'woocommerce':
Expand Down Expand Up @@ -57,34 +57,41 @@ const RecommendationsComponent = props => {
<QueryRewindStatus />
<QuerySite />
<QuerySitePlugins />
<Switch>
<Redirect exact from={ '/recommendations' } to={ '/recommendations' + redirectPath } />
<Route path="/recommendations/site-type">
<SiteTypeQuestion />
</Route>
<Route path="/recommendations/woocommerce">
<FeaturePrompt stepSlug="woocommerce" />
</Route>
<Route path="/recommendations/monitor">
<FeaturePrompt stepSlug="monitor" />
</Route>
<Route path="/recommendations/related-posts">
<FeaturePrompt stepSlug="related-posts" />
</Route>
<Route path="/recommendations/creative-mail">
<FeaturePrompt stepSlug="creative-mail" />
</Route>
<Route path="/recommendations/site-accelerator">
<FeaturePrompt stepSlug="site-accelerator" />
</Route>
<Route path="/recommendations/summary">
<Summary />
</Route>
</Switch>
{ isLoading ? (
<div className="jp-recommendations__loading">
<LoadingCard />
</div>
) : (
<Switch>
<Redirect exact from={ '/recommendations' } to={ '/recommendations' + redirectPath } />
<Route path="/recommendations/site-type">
<SiteTypeQuestion />
</Route>
<Route path="/recommendations/woocommerce">
<FeaturePrompt stepSlug="woocommerce" />
</Route>
<Route path="/recommendations/monitor">
<FeaturePrompt stepSlug="monitor" />
</Route>
<Route path="/recommendations/related-posts">
<FeaturePrompt stepSlug="related-posts" />
</Route>
<Route path="/recommendations/creative-mail">
<FeaturePrompt stepSlug="creative-mail" />
</Route>
<Route path="/recommendations/site-accelerator">
<FeaturePrompt stepSlug="site-accelerator" />
</Route>
<Route path="/recommendations/summary">
<Summary />
</Route>
</Switch>
) }
</>
);
};

export const Recommendations = connect( state => ( { step: getStep( state ) } ) )(
RecommendationsComponent
);
export const Recommendations = connect( state => ( {
isLoading: ! isRecommendationsDataLoaded( state ),
step: getStep( state ),
} ) )( RecommendationsComponent );
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@
box-shadow: 0px 2px 6px rgba( 0, 0, 0, 0.03 ), 0px 1px 2px rgba( 0, 0, 0, 0.03 );
border: 1px solid $gray-lighten-20;
}

.jp-recommendations__loading {
padding-top: 48px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,14 @@ const data = ( state = {}, action ) => {
};

const requests = ( state = {}, action ) => {
switch ( action ) {
switch ( action.type ) {
case JETPACK_RECOMMENDATIONS_DATA_FETCH:
return assign( {}, state, { isFetchingRecommendationsData: true } );
case JETPACK_RECOMMENDATIONS_DATA_FETCH_RECEIVE:
return assign( {}, state, {
isRecommendationsDataLoaded: true,
isFetchingRecommendationsData: false,
} );
case JETPACK_RECOMMENDATIONS_DATA_FETCH_FAIL:
return assign( {}, state, { isFetchingRecommendationsData: false } );
case JETPACK_RECOMMENDATIONS_UPSELL_FETCH:
Expand Down Expand Up @@ -116,6 +120,10 @@ export const isFetchingRecommendationsData = state => {
return !! state.jetpack.recommendations.requests.isFetchingRecommendationsData;
};

export const isRecommendationsDataLoaded = state => {
return !! state.jetpack.recommendations.requests.isRecommendationsDataLoaded;
};

export const isFetchingRecommendationsUpsell = state => {
return !! state.jetpack.recommendations.requests.isFetchingRecommendationsUpsell;
};
Expand All @@ -124,14 +132,9 @@ export const getDataByKey = ( state, key ) => {
return get( state.jetpack, [ 'recommendations', 'data', key ], false );
};

export const getStep = state => {
return '' === get( state.jetpack, [ 'recommendations', 'step' ], '' )
? getInitialRecommendationsStep( state )
: state.jetpack.recommendations.step;
};

const stepToNextStep = {
'setup-wizard-completed': 'site-type-question',
'setup-wizard-completed': 'summary',
'banner-completed': 'woocommerce',
'not-started': 'site-type-question',
'site-type-question': 'woocommerce',
woocommerce: 'monitor',
Expand Down Expand Up @@ -169,12 +172,14 @@ export const isFeatureActive = ( state, featureSlug ) => {
case 'woocommerce':
return !! isPluginActive( state, 'woocommerce/woocommerce.php' );
default:
throw `Unknown featureSlug in isFeatureEnabled() in recommendations/reducer.js: ${ featureSlug }`;
throw `Unknown featureSlug in isFeatureActive() in recommendations/reducer.js: ${ featureSlug }`;
}
};

const isStepEligibleToShow = ( state, step ) => {
switch ( step ) {
case 'setup-wizard-completed':
case 'banner-completed':
case 'not-started':
return false;
case 'site-type-question':
Expand All @@ -195,6 +200,21 @@ const getNextEligibleStep = ( state, step ) => {
return nextStep;
};

export const getStep = state => {
const step =
'' === get( state.jetpack, [ 'recommendations', 'step' ], '' )
? getInitialRecommendationsStep( state )
: state.jetpack.recommendations.step;

// These steps are special cases set on the server. There is technically no
// UI to display for them so the next eligible step is returned instead.
if ( [ 'setup-wizard-completed', 'banner-completed' ].includes( step ) ) {
return getNextEligibleStep( state, step );
}

return step;
};

export const getNextRoute = state => {
const currentStep = getStep( state );
const nextStep = getNextEligibleStep( state, currentStep );
Expand Down
64 changes: 64 additions & 0 deletions projects/plugins/jetpack/_inc/jetpack-recommendations-banner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* global jp_banner */

( function ( $ ) {
var recommendationsBanner = $( '#jp-recommendations-banner-main' );
var recommendationsBannerForm = $( '#jp-recommendations-banner__form' );
var recommendationsBannerContinue = $( '#jp-recommendations-banner__continue-button' );
var recommendationsBannerDismiss = $( '#jp-recommendations-banner__notice-dismiss' );

recommendationsBannerForm.on( 'change', function ( event ) {
if (
'checkbox' === event.target.type &&
event.target.parentElement &&
'label' === event.target.parentElement.tagName.toLowerCase()
) {
var isChecked = $( 'label.checked input[name="' + event.target.name + '"]' ).length > 0;
if ( isChecked ) {
event.target.parentElement.classList.remove( 'checked' );
} else {
event.target.parentElement.classList.add( 'checked' );
}
}
} );

recommendationsBannerContinue.on( 'click', function () {
var fieldNames = [ 'personal', 'business', 'store', 'other' ];
var formData = {};
fieldNames.forEach( function ( name ) {
formData[ name ] = $( "input[name='" + name + "']" ).prop( 'checked' );
} );

$.post(
jp_banner.ajax_url,
{
action: 'jetpack_recommendations_banner',
nonce: jp_banner.nonce,
personal: formData.personal,
business: formData.business,
store: formData.store,
other: formData.other,
},
function ( response ) {
if ( true === response.success ) {
window.location.assign( jp_banner.recommendations_url );
}
}
);
} );

recommendationsBannerDismiss.on( 'click', function () {
$( recommendationsBanner ).hide();

var data = {
action: 'jetpack_recommendations_banner',
nonce: jp_banner.nonce,
dismissBanner: true,
};

$.post( jp_banner.ajax_url, data, function ( response ) {
if ( true !== response.success ) {
$( recommendationsBanner ).show();
}
} );
} );
} )( jQuery );
Loading

0 comments on commit 3e87c6b

Please sign in to comment.