trewknowledge / GDPR

This plugin is meant to assist a Controller, Data Processor, and Data Protection Officer (DPO) with efforts to meet the obligations and rights enacted under the GDPR.
https://wordpress.org/plugins/gdpr/
GNU General Public License v2.0
149 stars 44 forks source link

Headers already sent error - fixed? #247

Closed AndyLeeRobinson closed 4 years ago

AndyLeeRobinson commented 5 years ago

Just noticed my error log filling up with these - here's the result of 1 request:

PHP Warning: Cannot modify header information - headers already sent in docroot/wp-content/plug ins/gdpr/public/class-gdpr-public.php on line 329 PHP Stack trace: PHP 1. {main}() docroot/wp-cron.php:0 PHP 2. require_once() docroot/wp-cron.php:39 PHP 3. require_once() docroot/wp-load.php:37 PHP 4. require_once() docroot/wp-config.php:108 PHP 5. do_action() docroot/wp-settings.php:505 PHP 6. WP_Hook->do_action() docroot/wp-includes/plugin.php:465 PHP 7. WP_Hook->apply_filters() docroot/wp-includes/class-wp-hook.php:310 PHP 8. GDPR_Public->set_plugin_cookies() docroot/wp-includes/class-wp-hook.php:286 PHP 9. setcookie() docroot/wp-content/plugins/gdpr/public/class-gdpr-public.php:332 PHP Warning: Cannot modify header information - headers already sent in docroot/wp-content/plugins/gdpr/public/class-gdpr-public.php on line 368 PHP Stack trace: PHP 1. {main}() docroot/wp-cron.php:0 PHP 2. require_once() docroot/wp-cron.php:39 PHP 3. require_once() docroot/wp-load.php:37 PHP 4. require_once() docroot/wp-config.php:108 PHP 5. do_action() docroot/wp-settings.php:505 PHP 6. WP_Hook->do_action() docroot/wp-includes/plugin.php:465 PHP 7. WP_Hook->apply_filters() docroot/wp-includes/class-wp-hook.php:310 PHP 8. GDPR_Public->set_plugin_cookies() docroot/wp-includes/class-wp-hook.php:286 PHP 9. setcookie() docroot/wp-content/plugins/gdpr/public/class-gdpr-public.php:368

Every time wordpress does a cron job, the gdpr plugin tries to set a cookie and fails because headers have already been sent. I didn't dig deeper and use wireshark so don't know exactly what's going on, but obviously, the server calling itself should not have to deal with any GDPR cookies. I fixed it by adding a line to class-gdpr-public.php:

public function set_plugin_cookies() {
+ if (isset($_SERVER['SCRIPT_NAME']) && preg_match('|/wp-cron\.php$|',$_SERVER['SCRIPT_NAME'])) return;

There may be a better way to do it, but this works for me. No cookies get sent whether wp-cron.php is accessed locally or from the web, which is just as well because it returns 0 bytes anyway! It's quite possible nobody ever noticed this if they don't have access to their error logs, or don't check them!

Adding this to wp-config.php and setting up a system cron task also cures the problem, but not every wp instance has crontab capability. define('DISABLE_WP_CRON', true);

I haven't pulled code before, but hopefully someone can look at this and add it.

fclaussen commented 4 years ago

Sorry for taking so long to get back to you. We've released an update yesterday to check for CRON before running that function