Wordpress - How to use the PHP header() function - wordpress

I need to use PHP headers like header( 'Location: http://location.com' ); or header("Content-disposition: attachment; filename=$fileName"); from my wordpress plugin but it won't seem to how. I know that they need to be used before the page header is called, so I tried using the init hook:
add_action('init', 'test');
function test() {
header( 'Location: http://location.com' ) ;
}
but it didn't work.

If you want to redirect any page then use wp_redirect() method.. OR if you want to set the specific headers to make the content downloadable.. use below sample..code...
Suppose your url is like.. http://example.com/download/data.csv
add_action('template_redirect','yoursite_template_redirect');
function yoursite_template_redirect() {
if ($_SERVER['REQUEST_URI']=='/downloads/data.csv') {
header("Content-type: application/x-msdownload",true,200);
header("Content-Disposition: attachment; filename=data.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo 'data';
exit();
}
}

Related

undefined function wp_redirect() in custom file

I'm trying to redirect user to search page having customized query. I'm stuck with wp_redirect() and getting error:
Fatal error: Uncaught Error: Call to undefined function wp_redirect()
Here is my redirection code:
customFile.php
<?php /* Template Name: customFile*/ ?>
<?php
// Logic to build $cSearch
// $cSearch is generated above in this file
$baseUrl = site_url().'/?s='. $cSearch;
wp_redirect( $baseUrl, 302 );
exit();
This file is required once in main plugin file.
I guessing that you try to use wp_redirect before the function included by wordpress.
Try this:
add_action( 'template_redirect', function() {
$baseUrl = site_url().'/?s='. $cSearch;
wp_redirect( $baseUrl, 302 );
exit();
} );
Try with this code
<?php /* Template Name: customFile*/ ?>
<?PHP
if (!defined('ABSPATH')) {
require_once(dirname(__FILE__) . '/wp-load.php');
}
// Logic to build $cSearch
// $cSearch is generated above in this file
$baseUrl = site_url().'/?s='. $cSearch;
wp_redirect( $baseUrl, 302 );
exit();

Error with wp_redirect

I want to redirect admin users to a maintenance page (https://mysite/maintenance/), but firefox tells me the redirection is not correctly made
add_action( 'template_redirect', 'custom_redirect' );
function custom_redirect()
{
if (current_user_can('administrator')) {
wp_redirect( home_url('/maintenance/') );
exit;
}
}
Have you an idea ?
You should be using the template_include filter for this:
add_filter('template_include', 'wpse_44239_template_include', 1, 1);
function wpse_44239_template_include($template){
if (current_user_can('administrator')) {
wp_redirect( home_url('/maintenance/') );
exit;
}
return $template;
}
template_redirect is the action called directly before headers are sent for the output of the rendered template. It's a convenient hook to do 404 redirects, etc... but shouldn't be used for including other templates paths as WordPress does this innately with the 'template_include' filter.
template_include and single_template hooks deal ONLY with the path of the template used for rendering the content. This is the proper place to adjust a template path.
What is the specific error Firefox is reporting? Sounds like it could be an infinite redirect loop. I would suggest adding a check to make sure you're not already on the maintenance page, ie:
add_action( 'template_redirect', 'custom_redirect' );
function custom_redirect()
{
if (current_user_can('administrator'))
{
global $wp;
$current_url = home_url( $wp->request );
$position = strpos( $current_url , '/maintenance/' );
if ($position===FALSE) {
wp_redirect( home_url('/maintenance/') );
exit;
}
}
}

Wordpress add_filter after post

I'm trying to add custom plugin after single post content. I have tried with add_filter and add_action to get my plugin printed out.
if(!defined('ABSPATH')) exit;
function customPlug_plugin_install()
{
}
register_activation_hook(__FILE__, 'customPlug_plugin_install');
function customPlug_plugin_scripts()
{
wp_register_script('customPlug_script', plugin_dir_url(__FILE__), 'js/customplug.js', '1.0', true);
wp_register_script('customPlug_bootstrap_script', plugin_dir_url(__FILE__), 'js/customplug.js', '1.0', true);
wp_register_script('customPlug_script', plugin_dir_url(__FILE__), 'js/customplug.js', '1.0', true);
wp_enqueue_script('customPlug_script');
}
function my_plugin($content) {
$content = "Custom Plugin Content";
return $content;
}
add_action('the_content', 'my_plugin');
However, this is just returning either the plugin content, or the_content if I comment out add_filter or add_action
You're overwriting current content. You should concatenate your content to current content with .
function my_plugin($content)
{
$content. = "Custom Plugin Content";
return $content;
}

Header location doesn't work in my wordpress plugin.

I'm writing an Wordpress plugin. With this plugin I update some data. The query and updating works fine, but my header("location: url"); doesn't work. If I place an echo, it won't give any error that the headers already send. It looks it doesn't do anything with those lines. My code...
<?php require_once('../../../wp-config.php');
$baanstatus_table=$wpdb->prefix . 'baanstatus';
$id = $_GET['id'];
$bijgewerkt =$_GET['bijgewerkt'];
$baanstatus= $_GET['baanstatus'];
$handicarts = $_GET['handicarts'];
$trolleys = $_GET['trolleys'];
$winterontheffing = $_GET['winterontheffing'];
$zomergreens = $_GET['zomergreens'];
$qualifying = $_GET['qualifying'];
$onderhoud_greens = $_GET['onderhoud_greens'];
$onderhoud_anders = $_GET['onderhoud_anders'];
$opmerkingen = $_GET['opmerkingen'];
global $wpdb;
$data_array =array('id' => $id,
'bijgewerkt' => $bijgewerkt,
'baanstatus' => $baanstatus,
'handicarts' => $handicarts,
'trolleys' => $trolleys,
'winterontheffing' =>$winterontheffing,
'zomergreens' =>$zomergreens,
'qualifying' =>$qualifying,
'onderhoud_greens' =>$onderhoud_greens,
'onderhoud_anders' =>$onderhoud_anders,
'opmerkingen' =>$opmerkingen
);
$where =array('id' => $id);
$wpdb->update( $baanstatus_table, $data_array, $where );
header("location:http://almeerderhout.fcklap.com/wp-admin/options-general.php?page=my-unique-identifier");
exit();
?>
Perhaps you should try the javascript, instead of PHP location.
<?php
echo '<script>location.href="http://almeerderhout.fcklap.com/wp-admin/options-general.php?page=my-unique-identifier";</script>';
?>
The below code will help you
<?php
wp_redirect( $location, $status );
exit;
?>
The above wordpress function will use to redirect Codex Link function reference
You should hook your plugin to a proper Wordpress action to avoid the "headers already sent error" when trying to redirect.
I found that a good place to perform redirects is the template_redirect action, so you can write something like this:
function do_something_then_redirect() {
// do something with $_GET or $_POST data
// then redirect to some url defined in the $redirect_url variable
wp_redirect($redirect_url);
die;
}
add_action('template_redirect', 'do_something_then_redirect');

Wordpress admin widget that exports data

I've been coding in PHP for a long time, but I'm currently writing my first Wordpress plugin. The plugin's goals are:
Display a form on a public-facing page to collect simple data from
site visitors (first/last name, etc)
Provide a way for admins export the data
I've got a plugin that successfully creates a table on activation and a shortcode that provides a form which successfully stores the submitted data in the database.
On the back-end, I have a dashboard widget that currently displays some stats about the submissions, and my last task is to provide a button to export those stats to CSV, and that's where I'm stumped. I'm not sure how to handle this in WP world...in the past, I would have had the button open a new window to a page that does the exporting and echos a CSV string to the page along with headers that indicate it's a binary file so it's downloaded. In WP, how do I accomplish this? Do I put a PHP script in my plugin directory and have my widget open that page? If so, how does that page gain access to $wpdb to handle the data access?
Here is my code (just for the dashboard widget part) as it stands now:
<?php
/*
Plugin meta details
*/
add_action('init', 'myplugin_buffer_start');
add_action('wp_footer', 'myplugin_buffer_end');
function myplugin_ob_callback($buffer) {
// You can modify buffer here, and then return the updated code
return $buffer;
}
/**
* Action: init
* Runs after WP has finished loading but before any headers are sent, user is already authenticated at this point
* Good for intercepting $_POST/$_GET
*/
function myplugin_buffer_start()
{
ob_start("myplugin_ob_callback");
}
/**
* Action wp_footer
* Triggered near the </body> tag of the user's template by the wp_footer() function.
*/
function myplugin_buffer_end()
{
ob_end_flush();
}
/****************************************************************
* Stats Dashboard Widgets
***************************************************************/
function myplugin_displaytestFormWidget_process()
{
$errors = array();
if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset ( $_POST['myplugin_export_button'] ))
{
ob_end_clean(); // erase the output buffer and turn off buffering...blow away all the markup/content from the buffer up to this point
global $wpdb;
$tableName = $wpdb->prefix . "myplugin_test_form";
$qry = "select Name, Date from $tableName order by Date desc";
//ob_start(); when I uncomment this, it works!
$result = $wpdb->get_results($qry, ARRAY_A);
if ($wpdb->num_rows)
{
$date = new DateTime();
$ts = $date->format("Y-m-d-G-i-s");
$filename = "myCsvFile-$ts.csv";
header( 'Content-Type: text/csv' );
header( 'Content-Disposition: attachment;filename='.$filename);
$fp = fopen('php://output', 'w');
//$headrow = $result[0];
//fputcsv($fp, array_keys($headrow));
foreach ($result as $data) {
fputcsv($fp, $data);
}
fclose($fp);
//when I uncomment these lines along with adding ob_start above, it works
//$contLength = ob_get_length();
//header( 'Content-Length: '.$contLength);
}
}
return myplugin_displaytestFormWidget();
}
function myplugin_displaytestFormWidget()
{
global $wpdb;
$tableName = $wpdb->prefix . "myplugin_test_form";
$submissionCount = $wpdb->get_var("select count(Id) from $tableName");
?>
<div><strong>Last entry: </strong>John Q. test (May 5, 2013)</div>
<div><strong>Total submissions: </strong> <?php echo $submissionCount ?></div>
<form id="myplugin_test_export_widget" method="post" action="">
<input type="submit" name="myplugin_export_button" value="Export All" />
</form>
<?php
}
function myplugin_addDashboardWidgets()
{
// widget_id, widget_name, callback, control_callback
wp_add_dashboard_widget(
'test-form-widget',
'test Form Submissions',
'myplugin_displaytestFormWidget_process'
);
}
/****************************************************************
* Hooks
***************************************************************/
//add_action('widgets_init', 'simple_widget_init');
add_action('wp_dashboard_setup', 'myplugin_addDashboardWidgets' );
// This shortcode will inject the form onto a page
add_shortcode('test-form', 'myplugin_displaytestForm_process');
register_activation_hook(__FILE__, 'myplugin_test_form_activate');
You can see in the myplugin_displayTestFormWidget function I'm displaying the form, I just don't know what to do with the button to make it all jive.
Can anyone assist?
At first add following code in your plugin
add_action('init', 'buffer_start');
add_action('wp_footer', 'buffer_end');
function callback($buffer) {
// You can modify buffer here, and then return the updated code
return $buffer;
}
function buffer_start() { ob_start("callback"); }
function buffer_end() { ob_end_flush(); }
Just at the top, right after the plugin meta info like
/**
* #package Word Generator
* #version 1.0
* ...
*/
// here goes the code given above, it'll solve the header sent error problem
And following code will dump a csv file
if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset ( $_POST['myplugin_export_button'] ))
{
// Somehow, perform the export
ob_clean();
global $wpdb;
$qry = 'your query';
$result = $wpdb->get_results($qry, ARRAY_A);
if ($wpdb->num_rows){
$date = new DateTime();
$ts = $date->format("Y-m-d-G-i-s");
$filename = "myCsvFile-$ts.csv";
header( 'Content-Type: text/csv' );
header( 'Content-Disposition: attachment;filename='.$filename);
$fp = fopen('php://output', 'w');
$headrow = $result[0];
fputcsv($fp, array_keys($headrow));
foreach ($result as $data) {
fputcsv($fp, $data);
}
fclose($fp);
$contLength = ob_get_length();
header( 'Content-Length: '.$contLength);
exit();
}
}
I've implemented similar functionality in another plugin I developed a while ago. I won't claim it's the best practice (I'm not 100% sure if there is such a thing in this instance) but it seemed like a clean and reliable solution for me at the time.
Picking up from where you left off, inside your myplugin_displayTestFormWidget_process function, let me just put some real and pseudo code that should get you rolling.
if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset ( $_POST['myplugin_export_button'] ))
{
// clear out the buffer
ob_clean();
// get the $wpdb variable into scope so you may use it
global $wpdb;
// define some filename using a timestamp maybe
// $csv_file_name = 'export_' . date('Ymd') . '.csv';
// get the results of your query
$result = $wpdb->get_results("SELECT * FROM your_table");
// loop your results and build your csv file
foreach($result as $row){
// put your csv data into something like $csv_string or whatever
}
header("Content-type: text/x-csv");
header("Content-Transfer-Encoding: binary");
header("Content-Disposition: attachment; filename=".$csv_file_name);
header("Pragma: no-cache");
header("Expires: 0");
echo $csv_string;
exit;
}
You mentioned you are pretty comfortable with PHP so I didn't really dig into the PHP aspects of getting this done.
Hope that helps, have fun!

Resources