Skip to content

Setup wizard: technical background screen#4833

Merged
westonruter merged 42 commits intodevelopfrom
feature/4705-setup-wizard-technical-question
Jun 20, 2020
Merged

Setup wizard: technical background screen#4833
westonruter merged 42 commits intodevelopfrom
feature/4705-setup-wizard-technical-question

Conversation

@johnwatkins0
Copy link
Copy Markdown
Contributor

@johnwatkins0 johnwatkins0 commented Jun 10, 2020

Summary

This will resolve #4705. It creates the "Are you technical?" screen that currently looks like this:

Screen Shot 2020-06-16 at 10 23 16 AM

Additional changes

  • Creates a AMP_User_Manager class to handle user-specific plugin features such as user meta and user capabilities.
  • Within that class, adds logic required to turn on amp developer tools by default for administrators or those with the amp_validate user capability. All other users are blocked from turning on developer tools at all.

Checklist

  • My pull request is addressing an open issue (please create one otherwise).
  • My code is tested and passes existing tests.
  • My code follows the Engineering Guidelines (updates are often made to the guidelines, check it out periodically).

@googlebot googlebot added the cla: yes Signed the Google CLA label Jun 10, 2020
@johnwatkins0 johnwatkins0 changed the title Feature/4705 setup wizard technical question Setup wizard: technical background screen Jun 10, 2020
Base automatically changed from feature/4702-choose-reader-theme to develop June 12, 2020 16:43
Comment on lines +22 to +71
const USER_OPTIONS_KEY = 'amp_user_options';

/**
* Key for the user option (stored in amp_features user meta) enabling or disabling developer tools.
*
* @var string
*/
const OPTION_DEVELOPER_TOOLS = 'developer_tools';

/**
* Sets up hooks.
*/
public static function init() {
add_filter( 'amp_setup_wizard_data', [ __CLASS__, 'inject_setup_wizard_data' ] );
add_action( 'rest_api_init', [ __CLASS__, 'register_user_meta' ] );
}

/**
* Registers user meta related to validation management.
*
* @since 1.6.0
*/
public static function register_user_meta() {
register_meta(
'user',
self::USER_OPTIONS_KEY,
[
'show_in_rest' => [
'schema' => [
'default' => [
self::OPTION_DEVELOPER_TOOLS => 'unset',
],
'type' => 'object',
'properties' => [
self::OPTION_DEVELOPER_TOOLS => [
'type' => 'string',
'enum' => [
'disabled',
'enabled',
'unset',
],
],
],
],
],
'single' => true,
'type' => 'object',
]
);
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can just have a simple scalar user meta key for amp_dev_tools_enabled. It can be a boolean because it will either be on or off. If the user cannot manage_options (or per #2673 amp_validate) then it will always be false. It would be true by default for users who have that capability. In other words, I don't think we need to have a separate option that controls whether dev tools are enabled or disabled by default for users.

@westonruter westonruter added this to the v1.6 milestone Jun 15, 2020
@johnwatkins0 johnwatkins0 changed the base branch from develop to feature/4811-visual-polish June 15, 2020 14:24
@johnwatkins0 johnwatkins0 self-assigned this Jun 15, 2020
Base automatically changed from feature/4811-visual-polish to develop June 15, 2020 23:05
@schlessera
Copy link
Copy Markdown
Collaborator

I think that https://github.com/phpstan/phpstan/blob/master/phpstan.phar points to a build of the latest commit, so alternatively, we could switch to that one while waiting for the fixes to be released.

@johnwatkins0
Copy link
Copy Markdown
Contributor Author

I've pushed updates to this, including merging in the dependency injection work. @westonruter Let me know if you think anything else needs to happen in this PR regarding validation capabilities. @schlessera The new class DevToolsUserAccess is added via the new infrastructure.

@johnwatkins0 johnwatkins0 requested a review from pierlon June 18, 2020 03:44
* Sets up hooks.
*/
public function register() {
add_action( 'rest_api_init', [ $this, 'register_rest_field' ] );
Copy link
Copy Markdown
Collaborator

@schlessera schlessera Jun 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this service is only needed for REST requests, it would be preferrable to make it "delayed" to only register at the rest_api_init action.

Right now, it always instantiates and then hooks into rest_api_init itself.

But for cases like this, the service container has smart behavior that adds an optimization.
If you add the Delayed interface with a registration action of rest_api_init instead, it will only instantiate at the rest_api_init action instead. So, as the instantiation itself is moved to that action, the service will not instantiate when the current request is not a REST request.

Copy link
Copy Markdown
Contributor Author

@johnwatkins0 johnwatkins0 Jun 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that makes sense. I've updated to add Delayed in cbf11ad. With this approach, I suppose there's no need to add callbacks to the rest_api_init hook, so I also changed register to call the register_rest_field method directly.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly, that's how I would have built it as well.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I assumed now you meant you've used the WordPress register_rest_field() method immediately within DevToolsUserAccess::register(). There's no need for the DevToolsUserAccess::register_rest_field() method anymore, that is just a superfluous method call overhead.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added it back in because we will need it later, to be able to add the user profile field.

@johnwatkins0 johnwatkins0 requested a review from schlessera June 18, 2020 13:41
Copy link
Copy Markdown
Collaborator

@schlessera schlessera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I originally meant.

* @action rest_api_init
*/
public function register() {
$this->register_rest_field();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for a bogus method call overhead here, you can just do the registration of the field directly within the register(), there's not much else to do anyway...

Suggested change
$this->register_rest_field();
register_rest_field(
'user',
self::USER_FIELD_DEVELOPER_TOOLS_ENABLED,
[
'get_callback' => [ $this, 'rest_get_dev_tools_enabled' ],
'update_callback' => [ $this, 'rest_update_dev_tools_enabled' ],
'schema' => [
'description' => __( 'Whether the user has enabled dev tools.', 'amp' ),
'type' => 'boolean',
],
]
);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good point! Updated in 71b8363

Comment on lines +49 to +68

/**
* Registers a rest field corresponding to the dev tools enabled user meta field.
*
* @since 1.6.0
*/
public function register_rest_field() {
register_rest_field(
'user',
self::USER_FIELD_DEVELOPER_TOOLS_ENABLED,
[
'get_callback' => [ $this, 'rest_get_dev_tools_enabled' ],
'update_callback' => [ $this, 'rest_update_dev_tools_enabled' ],
'schema' => [
'description' => __( 'Whether the user has enabled dev tools.', 'amp' ),
'type' => 'boolean',
],
]
);
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this anymore then.

Suggested change
/**
* Registers a rest field corresponding to the dev tools enabled user meta field.
*
* @since 1.6.0
*/
public function register_rest_field() {
register_rest_field(
'user',
self::USER_FIELD_DEVELOPER_TOOLS_ENABLED,
[
'get_callback' => [ $this, 'rest_get_dev_tools_enabled' ],
'update_callback' => [ $this, 'rest_update_dev_tools_enabled' ],
'schema' => [
'description' => __( 'Whether the user has enabled dev tools.', 'amp' ),
'type' => 'boolean',
],
]
);
}

westonruter and others added 3 commits June 19, 2020 17:07
…705-setup-wizard-technical-question

* 'develop' of github.com:ampproject/amp-wp: (77 commits)
  Supply DEFAULT_BASE_BRANCH in .travis.yml to fix wp-dev-lib issue
  Further fix PluginSuppressionTest
  Fix test logic for updating suppressed plugins
  Use simple comparison for version change since false causes PHP 7.4 error
  Update dependency autoprefixer to v9.8.1
  Update amphtml to v2006112352000
  Update dependency @babel/cli to v7.10.3
  Eliminate long-deprecated AMP_Blacklist_Sanitizer
  Sync amp-toolbox-test-suite
  Remove obsolete scripts to create-gutenberg-test-pos
  Eliminate removable references to ~master~ branch
  Improve variable name and comment
  Centralize option sanitization logic into Service
  Update Suppressed Plugins description
  Add remaining tests for PluginSuppression
  Account for widget_display_callback filter not being in the_widget() prior to WP 5.3
  Account for block editor not being present
  Add majority of tests for PluginSuppression; account for the_widget()
  Update dependency moment to v2.27.0
  Configure ServiceBasedPlugin for plugin use instead of theme use
  ...
* @return string Registration action to use.
*/
public static function get_registration_action() {
return 'rest_api_init';
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If not in this PR, in a subsequent PR we'll need to expand this so that we can also register a user profile field. We should perhaps not use Delayed in that case.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 307aa8c

);
}

return update_user_meta( $user->ID, self::USER_FIELD_DEVELOPER_TOOLS_ENABLED, boolval( $new_value ) );
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than storing a boolean, WordPress core stores a string "true" and "false" for user options:

image

This gets around the problem of storing a true boolean value in a MySQL TEXT field. I think we should do the same.

Suggested change
return update_user_meta( $user->ID, self::USER_FIELD_DEVELOPER_TOOLS_ENABLED, boolval( $new_value ) );
return update_user_meta( $user->ID, self::USER_FIELD_DEVELOPER_TOOLS_ENABLED, wp_json_encode( (bool) $new_value );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 3139da7.

Something to think about is that when a user is created in WordPress, it will by default supply all the user meta for, including those boolean options. So it will set the meta for rich_editing, syntax_highlighting, show_admin_bar_front, and comment_shortcuts. See the code in wp_insert_user(): https://github.com/WordPress/wordpress-develop/blob/1db25e3d3841e47e07eb71bf2b2c609cb37e71a1/src/wp-includes/user.php#L1763-L1774

That being the case, it's different that we are not providing an initial value here. Nevertheless, I think it's probably the right call because we don't know what the user's default choice should be.

Comment on lines +68 to +76
$meta = get_user_meta( $user['id'] );

if ( is_array( $meta ) && array_key_exists( self::USER_FIELD_DEVELOPER_TOOLS_ENABLED, $meta ) ) {
return boolval(
is_array( $meta[ self::USER_FIELD_DEVELOPER_TOOLS_ENABLED ] ) && ! empty( $meta[ self::USER_FIELD_DEVELOPER_TOOLS_ENABLED ] )
? reset( $meta[ self::USER_FIELD_DEVELOPER_TOOLS_ENABLED ] )
: $meta[ self::USER_FIELD_DEVELOPER_TOOLS_ENABLED ]
);
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per below, this could then be simplified to:

Suggested change
$meta = get_user_meta( $user['id'] );
if ( is_array( $meta ) && array_key_exists( self::USER_FIELD_DEVELOPER_TOOLS_ENABLED, $meta ) ) {
return boolval(
is_array( $meta[ self::USER_FIELD_DEVELOPER_TOOLS_ENABLED ] ) && ! empty( $meta[ self::USER_FIELD_DEVELOPER_TOOLS_ENABLED ] )
? reset( $meta[ self::USER_FIELD_DEVELOPER_TOOLS_ENABLED ] )
: $meta[ self::USER_FIELD_DEVELOPER_TOOLS_ENABLED ]
);
}
$meta_value = get_user_meta( $user['id'], self::USER_FIELD_DEVELOPER_TOOLS_ENABLED, true );
if ( '' !== $meta_value ) ) {
return rest_sanitize_boolean( $meta_value );
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 3139da7

@westonruter westonruter merged commit dc29d81 into develop Jun 20, 2020
@westonruter westonruter deleted the feature/4705-setup-wizard-technical-question branch June 20, 2020 05:48
@westonruter westonruter added the Changelogged Whether the issue/PR has been added to release notes. label Jul 17, 2020
@johnwatkins0 johnwatkins0 added the WS:UX Work stream for UX/Front-end label Aug 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Changelogged Whether the issue/PR has been added to release notes. cla: yes Signed the Google CLA WS:UX Work stream for UX/Front-end

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wizard step: Asking user if they're technical

4 participants