Closed felixarntz closed 4 years ago
@felixarntz, IB is added. I know that you don't want to set the user input state to required
yet, but I think it still makes sense to do it in the admin_init
hook to prevent invoking user input settings endpoint on every page load. I have added it to IB.
@eugene-manuilov I think it's okay for the user input endpoint to be invoked because the results are cached. It would only fire a request once a week (or otherwise when the data expired). Whether the value is required
or not shouldn't affect that at all, this check is only done for knowing whether the value should be set to completed
or not (completed
is not the opposite of required
here). Potentially we could explore using another flag value like missing
(both missing
and required
would mean that the settings are not completed
, with different nuance), that way we would only need to check the user input settings data if the value is empty. What do you think?
Regarding the IB specifically:
If yes, sets
user_input_state
setting tocompleted
, otherwiserequired
.
See above, this is not correct - only completed
should be set, otherwise nothing, or if we introduce missing
, then missing
should be set. required
is set once somebody with empty or missing
starts the setup flow (should not happen here though).
VALUE_DISMISSED
withdismissed
value.
This should not be a possible value, dismissal is purely handled on the client. We might want to replace this with VALUE_MISSING
though, see above, to only run the admin_init
check for the one case where the setting is not initialized.
Step 4
- Update the
GoogleSitekitDashboard
component in theassets/js/googlesitekit-dashboard.js
file to retrieveuserInputState
value using theuseSelect
hook.- Check if
userInputState
equals torequired
and redirect the user to thegooglesitekit-user-input
screen usinggetAdminURL
selector from thecore/site
datastore.
This redirect should happen server-side (e.g. in Screens
class), we shouldn't need to first start loading JS, which might cause some flashing of the dashboard and would also easily allow avoiding the redirect via DevTools etc.
@felixarntz I have updated IB to address your feedback. As to the missing
flag, I think we don't need it because it is the same thing as an empty value in the user input state setting.
This redirect should happen server-side (e.g. in Screens class), we shouldn't need to first start loading JS, which might cause some flashing of the dashboard and would also easily allow avoiding the redirect via DevTools etc.
Ok, updated IB to make the redirect in the Authentication class since it has everything required to do it.
@eugene-manuilov
As to the
missing
flag, I think we don't need it because it is the same thing as an empty value in the user input state setting.
Right, it's kind of the same, the reason I brought it up for consideration is that it would allow us to not check user input settings if missing
was set. Basically:
admin_init
would only check user input settings if the flag is empty / not set. It then sets it to either missing
or completed
.missing
otherwise means the same as empty / not set, it would allow the above logic to be skipped if not needed.We don't need to add it, but may be worth it.
@felixarntz I think it is worth adding missing
value because it will remove a need to send unnecessary requests to the proxy server. IB is updated.
@eugene-manuilov
Checks the current value of the user input state setting and returns if it equals to
completed
ormissing
;
It should return if it's any non-empty value (just for the uninitialized state it should get user input settings to check it)
Sends a GET request to the
REST_Routes::REST_ROOT . '/core/user/data/user-input-settings'
endpoint
Let's not send a REST request when we're already in PHP (even though we could do that internally). We should be able to use the User_Input_Settings
class directly.
Add another
admin_init
hook to redirect the user to thegooglesitekit-user-input
page if the current page isgooglesitekit-dashboard
and the user input state setting equals torequired
.
Maybe we should do this in the initialization callback for the googlesitekit-dashboard
screen, within Screens
class?
It should return if it's any non-empty value (just for the uninitialized state it should get user input settings to check it)
Yep, makes sense, updated.
Let's not send a REST request when we're already in PHP (even though we could do that internally). We should be able to use the User_Input_Settings class directly.
Maybe we should do this in the initialization callback for the googlesitekit-dashboard screen, within Screens class?
I would avoid doing it because it requires re-instantiating User_Input_Settings
and User_Input_State
classes with their dependencies in Screens
and Authentication
classes. It'll make the codebase slightly more complicated and a bit more coupled which is worse than calling the rest_do_request
function and adding another admin_init
hook. If we had a dependency injection, we would easily do what you suggest because we could get User_Input_Settings
and User_Input_State
objects from a DI container without creating duplicates. But for now, I think it worth doing it as it states in the IB now.
Let me know what you think about it. If you still want to move it, I can update the IB.
@eugene-manuilov I think it would make sense to instantiate User_Input_Settings
in the constructor of Authentication
and assign it to a class property, similar to how most other general authentication-related classes are instantiated there. I'd prefer to avoid making an internal REST request, and with this approach, which is already established, we don't have to re-instantiate the classes.
Let's then keep the redirection in an admin_init
hook within Authentication
like you suggested, relying on $this->user_input_settings
as well.
@felixarntz ok, updated.
IB ✅
I tested this a fair bit and found that everything works as expected. QA ✅
Regarding the constraint on possible values for googlesitekit_user_input_state
, this seems to be better implemented using a sanitize callback (get_sanitize_callback
in User_Input_State
) rather than only in User_Input_State::set
. That way the logic applies more globally, e.g. setting via REST or CLI as well.
This follows the IB and does work as expected so I can't say it's a QA failure but a suggested enhancement that would be quick to do. Thoughts @felixarntz ?
@aaemnnosttv Good catch! Let's open a follow-up issue for that.
@felixarntz I opened https://github.com/google/site-kit-wp/issues/2323 as a follow-up.
Moving this one forward to approval 👍
Depending on whether a user is connecting to Site Kit or whether a user is returning to Site Kit after having already used a previous version of the plugin, the way they should be exposed to the new user input screen should behave differently. This issue is about implementing the necessary logic to determine the user's state regarding user input.
Do not alter or remove anything below. The following sections will be managed by moderators only.
Acceptance criteria
googlesitekit_user_input_state
.admin_init
, run a hook to check whether user input settings were previously completed (if the flag value is not already “completed”):googlesitekit-dashboard
admin screen, check if the new user setting is currently “required”. If yes, redirect to the newgooglesitekit-user-input
screen from #2038.core/user
storegetUserInputState()
. It should rely on a server-provided value via_googlesitekitUserData.userInputState
.Note that this won't do anything user-facing via the above implementation, which is on purpose because the final pieces can only be implemented once everything is ready to be launched in production. For example, setting the new user setting to "required" or "dismissed" will happen later.
Implementation Brief
Step 1
Core\Authentication\User_Input_State
class that extendsCore\Storage\User_Setting
.OPTION
constant withgooglesitekit_user_input_state
as its value.VALUE_REQUIRED
withrequired
value;VALUE_COMPLETED
withcompleted
value;VALUE_MISSING
withmissing
value.set
method to verify the incoming value isrequired
,completed
,missing
, or empty. If the value is valid pass it to the parent method. If not, then just returnfalse
.Step 2
In the
Authentication
class:User_Input_State
class as private propertyuser_input_state
;User_Input_Settings
class as private propertyuser_input_settings
;register
method in theregister
method of theAuthentication
class;admin_init
action that calls theverify_user_input_settings
method;verify_user_input_settings
method that:user_input_settings->get_settings()
functionuser_input_state
setting tocompleted
, otherwisemissing
.googlesitekit_user_data
filter that addsuserInputState
property to the filtered data using value received from theuser_input_state::get
method.admin_init
hook to redirect the user to thegooglesitekit-user-input
page if the current page isgooglesitekit-dashboard
and the user input state setting equals torequired
.Step 3
In the
core/user
datastore (user-info.js
file):receiveUserInputState
action that accepts user input state value and triggers appropriate action with the incoming value as a payload;userInputState
property of the store state object.getUserInputState
resolver that takesuserInputState
property from the_googlesitekitUserData
object and yieldsreceiveUserInputState
action. It should behaive similar togetConnectURL
resolvergetUserInputState
to thecore/user
store which returnsuserInputState
from the store state object.QA Brief
sync_with_proxy
function - see #2036 for details.wp_googlesitekit_user_input_state
option torequired
Changelog entry