I've run into a headers already send problem while adding functionality to one of my plugins. I wish to send my 301 redirect header after some checks to deteremine if the contents of the page is obsolete. I have a wordpress page that contains just the shortcode [shortcode]. Then in my plugin I hook into init to register my shortcode using the following snippet of code
function __construct()
{
//register an activation hook for the plugin
register_activation_hook(__FILE__, array(
&$this,
'install_bnw'
));
//Hook up to the init action
add_action('init', array(
&$this,
'start_session'
), 1);
add_action('init', array(
&$this,
'class_loader'
));
add_action('init', array(
&$this,
'init_bnw'
));
add_filter('wpseo_canonical', array(
&$this,
'wpseo_canonical'
));
}
/**
* Runs when the plugin is activated
*/
function install_bnw()
// TODO: Add check if the *** plugin is currently activated and if it can be reached from this plugin.
{
// do not generate any output here
}
/**
* Starts a session before any output is generated.
* TODO: Might not be the most efficient way to handle sessions, needs improvement.
*/
public function start_session()
{
if (!session_id()) {
session_start();
}
}
/**
* Runs when the plugin is initialized.
* Adds filters to wordpress functions and calls functions that need to be executed.
*/
function init_bnw()
{ // Adds all the shortcodes that need to be added.
$this->add_shortcodes();
// -- Some more code --
}
/**
* Autoloader that uses template_autoloader to load class files from a predetermined location.
*/
function class_loader()
{
// register an autoloader function for template classes
spl_autoload_register(array(
&$this,
'template_autoloader'
));
}
/**
* Used by the class_loader function to load classes from files but only if the files exist to ensure this plugin works with other plugins.
* @param $class
* @return bool that tells if the include worked.
* @throws Exception
*
*/
function template_autoloader($class)
{
$classPath = "includes/$class.php";
// Checks if the file exists for compatibility with other plugins using the spl_autoload functionality.
if (file_exists(__DIR__ . '/' . $classPath)) {
include_once $classPath;
return true;
} else {
return false;
}
}
/**
* Contains all the shortcodes that need to be added to wordpress in order for this plugin to function.
*/
private function add_shortcodes()
{
// Add all the shortcodes that need to be added here.
// --Some shortcodes here --
add_shortcode('shortcode', array(
&$this,
'shortcodeDesinationFunction'
));
// -- More shortcodes --
}
The function shortcodeDestinationFunction loads a class, with an empty constructor and then calls the following function:
function showTraining()
{
// -- Do some data getting and business logic here but no outputting --
// If training is in the past
if($startdate < $currentdate)
{
// -- Some more data getting function that don't output anthing
$newLocation = "/text/text/$subjectLabel/$trainingLevel";
// Disable caching for testing
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // past date to encourage expiring immediately
header ('HTTP/1.1 301 Moved Permanently');
header ('Location:'.$newLocation);
}
// Some more code
As you can see I want the page that has this shortcode to be able to send a 301 redirect when a certain condition applies.
When I run the code I get the following error's (from the blackbox wordpress plugin):
Warning Cannot modify header information - headers already sent by (output started at /var/www/vhosts/bndev.int.bijlesnetwerk.nl/httpdocs/wp-includes/class.wp-styles.php:122) on line 183 in file /var/www/vhosts/bndev.int.bijlesnetwerk.nl/httpdocs/wp-content/plugins/BNWPweb/includes/examenTraining.php
Warning Cannot modify header information - headers already sent by (output started at /var/www/vhosts/bndev.int.bijlesnetwerk.nl/httpdocs/wp-includes/class.wp-styles.php:122) on line 184 in file /var/www/vhosts/bndev.int.bijlesnetwerk.nl/httpdocs/wp-content/plugins/BNWPweb/includes/examenTraining.php
Warning Cannot modify header information - headers already sent by (output started at /var/www/vhosts/bndev.int.bijlesnetwerk.nl/httpdocs/wp-includes/class.wp-styles.php:122) on line 186 in file /var/www/vhosts/bndev.int.bijlesnetwerk.nl/httpdocs/wp-content/plugins/BNWPweb/includes/examenTraining.php
Warning Cannot modify header information - headers already sent by (output started at /var/www/vhosts/bndev.int.bijlesnetwerk.nl/httpdocs/wp-includes/class.wp-styles.php:122) on line 187 in file /var/www/vhosts/bndev.int.bijlesnetwerk.nl/httpdocs/wp-content/plugins/BNWPweb/includes/examenTraining.php
Line 183 is the first header statement, and the line referenced from the wordpress core file contains the following:
} else {
echo $tag;
$this->print_inline_style( $handle );
}
Now my question is, how do I send a header via a plugin shortcode without getting the headers already send warning?
I have already googled quite a bit and I have read some stackexchange answer but none seem applicable, I don't think it's a problem with a random whitespace or one of my plugins outputting something that it isn't supposed to. I have also read Wordpress FAQ about headers already sent to no avail.
showTraining ()
hooked? It seems before redirecting something got printed from /wp-includes/class.wp-styles.php:122 Did you try to hook theshowTraining ()
function with 'template_redirect' hook?showTraining()
is a function of an class that is called by the functionshortcodeDesinationFunction()
which in turn hooks into init. Is template_redirect called before init?template_redirect
. Also, you should usewp_redirect()
: codex.wordpress.org/Function_Reference/wp_redirect