INN / Google-Analytics-Popular-Posts

A WordPress plugin that uses Google Analytics data to determine the most popular posts on your site and display a list of popular posts via the included widget.
https://wordpress.org/plugins/ga-popular-posts/
23 stars 7 forks source link

Modifying headers after sending them, in admin? #59

Closed benlk closed 7 years ago

benlk commented 7 years ago

Warning: Cannot modify header information - headers already sent by (output started at /srv/www/testing/htdocs/wp-includes/formatting.php:5075) in /srv/www/testing/htdocs/wp-content/plugins/ga-popular-posts/inc/analytic-bridge-blog-options.php on line 131

Seen at http://testing.dev/wp-admin/options-general.php?page=analytic-bridge

benlk commented 7 years ago

https://github.com/INN/Google-Analytics-Popular-Posts/blob/master/inc/analytic-bridge-blog-options.php#L127-L131

We can't be using header() here because the headers have already been sent.

To do:

  1. figure out why we're changing the headers, see if this can be done earlier in the page load
  2. delete the options (see #55)
  3. Try the sign-up process again
benlk commented 7 years ago

Dunno why we're changing the headers.

But moving the header modifications into a separate action (efe7fc6c6491000de02c578906e732284683ec71) fixes this enough that #61 begins to occur reliably.


  1. Paste in the google client ID and google client secret
  2. Press "Save Changes"
  3. https://github.com/INN/Google-Analytics-Popular-Posts/issues/61 consistently
benlk commented 7 years ago

61 might just be a case of the URL parameter being present when it shoudn't've been present.

After removing the code parameter from the URL, a Google_Auth_Exception for invalid code:

Fatal error: Uncaught Google_Auth_Exception: Invalid code in /srv/www/testing/htdocs/wp-content/plugins/ga-popular-posts/api/src/Google/Auth/OAuth2.php:88

Stack trace:

  1. /srv/www/testing/htdocs/wp-content/plugins/ga-popular-posts/api/src/Google/Client.php(120): Google_Auth_OAuth2->authenticate(NULL)
  2. /srv/www/testing/htdocs/wp-content/plugins/ga-popular-posts/AnalyticBridgeGoogleClient.php(189): Google_Client->authenticate(NULL)
  3. /srv/www/testing/htdocs/wp-content/plugins/ga-popular-posts/inc/analytic-bridge-blog-options.php(133): analytic_bridge_authenticate_google_client(NULL)
  4. /srv/www/testing/htdocs/wp-includes/class-wp-hook.php(298): analyticbridge_option_page_html('')
  5. /srv/www/testing/htdocs/wp-includes/class-wp-hook.php(323): WP_Hook->apply_filters('', Array)
  6. /srv/www/testing/htdocs/wp-includes/plugin.php(453): WP_Hook->do_action(Array)
  7. /srv/www/testing/htdocs/wp-admin/admin.php(222): do_action('settings_page_a...')
  8. /srv/www/testing/htdocs/wp-admin/options-general.php(10): require_once('/srv/www/ in /srv/www/testing/htdocs/wp-content/plugins/ga-popular-posts/api/src/Google/Auth/OAuth2.php on line 88

https://github.com/INN/Google-Analytics-Popular-Posts/blob/efe7fc6c6491000de02c578906e732284683ec71/inc/analytic-bridge-blog-options.php#L133-L135

        /* Google has posted an authenticate code back to us. */
        if ( isset($_GET['code']) ) {
            $client = analytic_bridge_authenticate_google_client($_GET['code']);
            // @see analyticbridge_google_authenticate_code_post();
        // No auth ticket loaded (yet).
        } elseif ( !get_option('analyticbridge_access_token') ) {
            $client = analytic_bridge_authenticate_google_client($_GET['code']);
            $client = analytic_bridge_google_client(false);
            echo "<a href='" . $client->createAuthUrl() . "'>Connect</a>";

Why are we using $_GET to generate $client? It's not set.

benlk commented 7 years ago

Fixed that in https://github.com/INN/Google-Analytics-Popular-Posts/commit/dc45e72a4de318d9b992baaa42442128f91b145f

Now, with the URL having $code set in it: http://testing.dev/wp-admin/options-general.php?page=analytic-bridge&code=snipped

Fatal error: Uncaught TypeError: Argument 1 passed to Google_Service_Oauth2::__construct() must be an instance of Google_Client, boolean given, called in /srv/www/testing/htdocs/wp-content/plugins/ga-popular-posts/inc/analytic-bridge-blog-options.php on line 369 and defined in /srv/www/testing/htdocs/wp-content/plugins/ga-popular-posts/api/src/Google/Service/Oauth2.php:52

Stack trace:

  1. /srv/www/testing/htdocs/wp-content/plugins/ga-popular-posts/inc/analytic-bridge-blog-options.php(369): Google_Service_Oauth2->__construct(false)
  2. /srv/www/testing/htdocs/wp-admin/includes/template.php(1343): analyticbridge_setting_api_token_connect_button(Array)
  3. /srv/www/testing/htdocs/wp-admin/includes/template.php(1302): do_settings_fields('analytic-bridge', 'largo_anaytic_b...')
  4. /srv/www/testing/htdocs/wp-content/plugins/ga-popular-posts/inc/analytic-bridge-blog-options.php(120): do_settings_sections('analytic-bridge')
  5. /srv/www/testing/htdocs/wp-includes/class-wp-hook.php(298): analyticbridge_option_page_html('')
  6. /srv/www in /srv/www/testing/htdocs/wp-content/plugins/ga-popular-posts/api/src/Google/Service/Oauth2.php on line 52

This is in the https://github.com/INN/Google-Analytics-Popular-Posts/tree/59-error-in-signup-process branch.

benlk commented 7 years ago

https://stackoverflow.com/questions/10827920/not-receiving-google-oauth-refresh-token/10857806#10857806

When you mess up the installation, you have to delete the app's access to your account in https://security.google.com/settings/u/0/security/permissions before retrying, because for some reason it only sends the required refresh token on the first try.

benlk commented 7 years ago

Removing code from the url solves this problem:

http://testing.dev/wp-admin/options-general.php?page=analytic-bridge&code=snipped

Fatal error: Uncaught TypeError: Argument 1 passed to Google_Service_Oauth2::__construct() must be an instance of Google_Client, boolean given, called in /srv/www/testing/htdocs/wp-content/plugins/ga-popular-posts/inc/analytic-bridge-blog-options.php on line 367 and defined in /srv/www/testing/htdocs/wp-content/plugins/ga-popular-posts/api/src/Google/Service/Oauth2.php:52 Stack trace: #0 /srv/www/testing/htdocs/wp-content/plugins/ga-popular-posts/inc/analytic-bridge-blog-options.php(367): Google_Service_Oauth2->__construct(false) #1 /srv/www/testing/htdocs/wp-admin/includes/template.php(1343): analyticbridge_setting_api_token_connect_button(Array) #2 /srv/www/testing/htdocs/wp-admin/includes/template.php(1302): do_settings_fields('analytic-bridge', 'largo_anaytic_b...') #3 /srv/www/testing/htdocs/wp-content/plugins/ga-popular-posts/inc/analytic-bridge-blog-options.php(120): do_settings_sections('analytic-bridge') #4 /srv/www/testing/htdocs/wp-includes/class-wp-hook.php(298): analyticbridge_option_page_html('') #5 /srv/www in /srv/www/testing/htdocs/wp-content/plugins/ga-popular-posts/api/src/Google/Service/Oauth2.php on line 52

So we need to figure out how to reliably remove the code parameter from the URL after the site does what it needs to do with it.

benlk commented 7 years ago

So new workflow:

  1. Remove any previous access from your site at https://security.google.com/settings/u/0/security/permissions or the equivalent URL for the Google account you are logged in with
  2. Enter the Client ID and client secret
  3. Press save
  4. Press the Google button
  5. Choose your login
  6. Accept the permissions warning
  7. The redirect occurs:
  8. Press update link at bottom of page (This really needs to be moved up later)
  9. Refresh the page
  10. Done?