Setup wizard: technical background screen#4833
Conversation
| 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', | ||
| ] | ||
| ); | ||
| } |
There was a problem hiding this comment.
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.
…ard-technical-question
…zard-technical-question
…-wizard-technical-question
…-wizard-technical-question
|
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. |
|
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 |
| * Sets up hooks. | ||
| */ | ||
| public function register() { | ||
| add_action( 'rest_api_init', [ $this, 'register_rest_field' ] ); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Yes, exactly, that's how I would have built it as well.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
I've added it back in because we will need it later, to be able to add the user profile field.
schlessera
left a comment
There was a problem hiding this comment.
This is what I originally meant.
src/Admin/DevToolsUserAccess.php
Outdated
| * @action rest_api_init | ||
| */ | ||
| public function register() { | ||
| $this->register_rest_field(); |
There was a problem hiding this comment.
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...
| $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', | |
| ], | |
| ] | |
| ); |
|
|
||
| /** | ||
| * 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', | ||
| ], | ||
| ] | ||
| ); | ||
| } |
There was a problem hiding this comment.
No need for this anymore then.
| /** | |
| * 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', | |
| ], | |
| ] | |
| ); | |
| } |
…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 ...
src/Admin/DevToolsUserAccess.php
Outdated
| * @return string Registration action to use. | ||
| */ | ||
| public static function get_registration_action() { | ||
| return 'rest_api_init'; |
There was a problem hiding this comment.
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.
src/Admin/DevToolsUserAccess.php
Outdated
| ); | ||
| } | ||
|
|
||
| return update_user_meta( $user->ID, self::USER_FIELD_DEVELOPER_TOOLS_ENABLED, boolval( $new_value ) ); |
There was a problem hiding this comment.
Rather than storing a boolean, WordPress core stores a string "true" and "false" for user options:
This gets around the problem of storing a true boolean value in a MySQL TEXT field. I think we should do the same.
| 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 ); |
There was a problem hiding this comment.
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.
src/Admin/DevToolsUserAccess.php
Outdated
| $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 ] | ||
| ); | ||
| } |
There was a problem hiding this comment.
Per below, this could then be simplified to:
| $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 ); | |
| } |

Summary
This will resolve #4705. It creates the "Are you technical?" screen that currently looks like this:
Additional changes
amp_validateuser capability. All other users are blocked from turning on developer tools at all.Checklist