Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display error when a plugin is activated which tries to do something incompatible with AMP #842

Closed
5 tasks done
MackenzieHartung opened this issue Jan 4, 2018 · 7 comments
Milestone

Comments

@MackenzieHartung
Copy link

MackenzieHartung commented Jan 4, 2018

Acceptance Criteria

AC1: On activating a plugin on wp-admin/plugins.php, if the plugin does something that’s not compatible with AMP, display an error at the top of the page
AC2: The error message will display the following text:. “ is not compatible with AMP, and could result in content displaying improperly on your site.”

Tasks

  • Add a "reporting" flag whenever something is removed by the output buffer sanitizer and use that to build the "Bad Plugin" error.
  • Report other things than just node removal, including enqueued scripts and styles.
  • Report errors related to unknown sources.
  • Add method to disable AMP sanitization to be able to debug what is going on?
  • Improve initialization process for how validation is requested.
@kienstra
Copy link
Contributor

kienstra commented Feb 7, 2018

Question About Approach

Hi @westonruter,
Using the sanitization reporting PR, what do you think about this approach:

  1. Before activating a plugin on /wp-admin/plugins.php,
  2. Make a request for the header of a single post page, like https://local.envi/?p=1633
  3. Store the AMP-Validation-Error from the header. Example:
{
"has_error": true,
"removed_nodes": {"script": 1},
"removed_attributes": null
}
  1. After the plugin activation, make another request like in step 2, and compare the AMP-Validation-Errorvalues.
  2. If there are 'removed_nodes' in step 4 that weren't present in step 2, display an error message.
  3. Possibly display in the notice the node(s) that the plugin added that the sanitizer removed.

Thanks, Weston 😄

@kienstra kienstra assigned kienstra and westonruter and unassigned westonruter and kienstra Feb 7, 2018
@westonruter
Copy link
Member

@kienstra I think that this will not give us complete results. A plugin may not do anything upon activation. It may require a user to actually do something, like add a widget or shortcode.

I think the best we can probably do here is:

  1. Watch for a plugin enqueueing a script or stylesheet. If a script or stylesheet gets removed by sanitizer, look for the wp-content/(themes|plugins)/(.+) directory the file is located in. And this would indicate which plugin or theme is doing something bad.
  2. And this is going to be more experimental, but we could maybe iterate over all of the $wp_filter->callbacks to find all added callbacks that are sourced from a theme or plugin. For example, an instance of a class could have its location looked up via ReflectionClass::getFilename(). Then for each one, we could wrap the callback with our own callback which then does output buffering before and after, and then we could look at the output to see if it contains anything invalid. It may be best to output some kind of HTML comment, like before and after (<!--before:jetpack--> ... <!--after:jetpack-->) and then later use the sanitizer to keep track of which plugin is was running at the time a node was removed.

@westonruter
Copy link
Member

Both of these checks would only be done when explicitly requested, especially the latter one because I imagine it would be expensive.

@westonruter
Copy link
Member

It should also be possible to use the similar approach for shortcodes. We could wrap each registered shortcode handler with a function that puts those milestone comments before and after. The sanitizer would then be able to know which shortcode was responsible for the illegal output. The specific theme or plugin could be identified via the Reflection API to fond the filename that contains the function or class.

kienstra pushed a commit that referenced this issue Feb 17, 2018
If a <script> or stylesheet gets removed,
store it in $removed_assets.
There isn't yet a way to report inline scripts.
Like <script type="text/javascript">myFunc();</script>.
This uses the 'src' attribute to find the plugin or theme.
kienstra pushed a commit that referenced this issue Feb 19, 2018
Iterate through all of the registered callbacks.
If a callback is from a plugin and outputs markup,
wrap the markup in comments.
Later, the sanitizer can identify which plugin
any illegal markup is from.
Thanks to @westonruter for this strategy.
kienstra pushed a commit that referenced this issue Feb 19, 2018
Also, address a Travis error.
Instead of testing for the presence of 'amp-wp,'
simply make it 'amp.'
This plugin seems to be in the directory 'amp-wp'
in the Travis tests.
kienstra pushed a commit that referenced this issue Feb 19, 2018
The plugin is in 'amp-wp' in some Travis tests.
So instead of expecting the plugin to be 'amp,'
Simply expect it to contain 'amp.'
kienstra pushed a commit that referenced this issue Feb 20, 2018
Add an extra parameter to track_removed().
If $source is passed, store that.
Then, if a node is removed,
look for the presence of $source.
kienstra pushed a commit that referenced this issue Feb 20, 2018
If the query var of 'validate' is present,
Output the previous validation response,
like on the post.php page.
But also add a 'plugins_with_invalid_output' value.
This includes all of the plugins that output markup
which had removed elements or attributes.
kienstra pushed a commit that referenced this issue Feb 20, 2018
This might have caused issues,
as the order of assignment is different in PHP 7.0.
So insted, access the array values.
kienstra pushed a commit that referenced this issue Feb 20, 2018
Substitute all uses of 'remove_invalid_callback'
With AMP_Validation_Utils::CALLBACK_KEY.
@kienstra kienstra assigned kienstra and unassigned westonruter Feb 20, 2018
kienstra pushed a commit that referenced this issue Feb 23, 2018
Props @westonruter.
This also needs to account for themes and mu-plugins.
kienstra pushed a commit that referenced this issue Feb 24, 2018
On Weston's suggestion,
as this can track nested plugins in themes.
Also, update PHPUnit tests for this.
kienstra pushed a commit that referenced this issue Feb 24, 2018
At Weston's suggestion,
as this needs to apply to themes.
kienstra pushed a commit that referenced this issue Feb 24, 2018
As Weston suggested, started with add_post_meta().
If that is false, get the post meta,
And append the new URL to the array.
kienstra pushed a commit that referenced this issue Feb 24, 2018
At Weston's suggestion.
For example, <!--before:plugin:amp-->
kienstra pushed a commit that referenced this issue Feb 24, 2018
The means of doing this might need improvement.
But this uses regexes,
based on the paths to the theme, plugin, and mu-plugin dirs.
kienstra pushed a commit that referenced this issue Feb 24, 2018
In Travis, this plugin is cloned as 'amp-wp'.
But developers usually clone it as 'amp'.
So remove the '-wp',
to avoid errors in Travis.
kienstra pushed a commit that referenced this issue Feb 26, 2018
Mostly resolve in favor of develop.
But apply some changes from branch add/842-plugin-validation.
Like the constant AMP_Validation_Utils::CALLBACK_KEY,
instead of 'remove_invalid_callback'.
kienstra pushed a commit that referenced this issue Feb 28, 2018
Display a notice on /wp-admin/plugins.php,
when a plugin has invalide markup on the home page.
@todos include improving validate_home().
There's now an error locally,
with a self-signed SSL certificate.
@kienstra
Copy link
Contributor

kienstra commented Feb 28, 2018

Discussion Is On PR

Most of the discussion and solution design for this issue is now taking place on this pull request.

kienstra pushed a commit that referenced this issue Mar 1, 2018
Per Weston's suggestion,
this outputs all of the URLs with plugin or theme errors.
@todos include the 're-check'
And removing the 'Add New' link on the post table.
kienstra pushed a commit that referenced this issue Mar 1, 2018
Correct an issue in improper vertical alignment.
And use constants in place of string literals.
kienstra pushed a commit that referenced this issue Mar 1, 2018
Only remove some items from post actions.
Keep the rest of the actions in place.
Like 'Restore' when in the trash.
Also, prevent displaying multiple plugins on plugins.php.
kienstra pushed a commit that referenced this issue Mar 1, 2018
This displays on the 'AMP Validation Errors' page.
@todo: implement this bulk action on the back-end.
kienstra pushed a commit that referenced this issue Mar 1, 2018
On the edit.php page,
there's a column for 'Incompatible Source'.
The way the sources are stored enables duplicated.
So use array_unique to prevent displaying more than one.
@westonruter westonruter self-assigned this Mar 7, 2018
@kienstra
Copy link
Contributor

kienstra commented Mar 8, 2018

Steps To Test

Hi @csossi,
Could you please test this?

plugins.php

  1. Go to the dev site /wp-admin/plugins.php page.
  2. Deactivate and activate the (test) plugin 'AMP Invalid.'
  3. Expected: the warning includes the name amp-invalid

plugin-activated

  1. Expected: clicking 'More details' drives to the 'Validation Status' page

Validation Status Page

  1. On the dev site /wp-admin section, go to 'AMP' > 'Validation Status.'
  2. Expected: each validation error has value(s) for 'Title,' 'Count,' 'Removed Elements,' 'Removed Attributes,' 'Incompatible Sources,' and 'Date.' The value '--' is acceptable. And the 'badge' has the number of error posts:

number-corresponds-to-errors

  1. Observe a plugin that's in the 'Incompatible Sources' column (shown below)
  2. Deactivate that plugin
  3. Click 'Recheck'

click-recheck

  1. Expected: that plugin no longer appears in the 'Incompatible Sources' column for that error. It may appear in other error posts.
  2. Reactivate the plugin
  3. Repeat Steps 1-7 above. But instead of clicking 'Recheck' inline,' select a few boxes and click 'Recheck' from 'Bulk Actions'

bulk-actions

  1. Expected: same as 6. above, but the deactivated plugin shouldn't appear in any of the rechecked errors.
  2. Go to the dev site dashboard
  3. Expected: the 'At a Glance' widget shows a message with the amount of error posts:

validation-errors-dashboard

Single Error post.php Page

  1. From the Validation Status page above, click 'Details' after hovering over one of the post titles.
  2. Find a plugin that's listed in the 'Sources' section, like 'amp-invalid':

plugin-deactivate-recheck

  1. Deactivate that plugin.
  2. Click 'Recheck on this page (shown above)
  3. Expected: that plugin is no longer listed in that post. It's possible that this redirects to the 'Validation Status' page if the page no longer has any error.

Troubleshooting
If there aren't any errors on the Validation Status page, deactivate and activate the 'AMP Invalid' plugin.

@kienstra kienstra assigned csossi and unassigned westonruter and kienstra Mar 8, 2018
@kienstra kienstra reopened this Mar 8, 2018
@csossi csossi removed their assignment Mar 16, 2018
@csossi
Copy link

csossi commented Mar 16, 2018

verified in QA

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants