Send pdf from wp_remote_get to browser - wordpress

I'm integrating a wordpress site with an external API. I have a form that posts to my server and I call a function on my server that makes a wp_remote_get call to the external API.
The external API returns a PDF, with headers like:
[date] => Fri, 18 Aug 2017 15:59:19 GMT
[x-powered-by] => Servlet/3.0
[cache-control] => no-cache
[content-type] => application/pdf;charset=utf-8
[content-language] => en-US
And the response body is the PDF in nasty string format, which seems like a good start.
How do I pass this PDF to the user's browser?
ie,
$response = wp_remote_get( $url, array ( //stuff the request needs));
if (is_wp_error ($response)) {
$error_message = $response->get_error_message();
echo "Something went wrong: $error_message";
} else {
//What here?
}
I have to hit my server first, cannot post the form directly to the external API.

I managed this by using javascript to redirect my form submit to a new window on my site, passing along the form information as URL params.
ie,
in my HTML:
<form onsubmit="return qrsDownload()">
And then in javascript:
function qrsDownload() {
// a bunch of jquery and processing to build the URL..
window.open(url, 'My Title', 'width=800, height=600');
}
The page I opened was a single-use page template I created, that I omitted the standard WP templates in (so no header, no footer, no wordpress loop), and in that page's php file:
<?php
if (isset($_GET['someParam'])) {
// started off with logic to verify that I had the params needed
// because anybody could just jump directly to this page now
}
$url = "whateverurl.com/myendpoint";
// additional logic to set up the API call
$server_response = wp_remote_get($url, $args);
if (is_wp_error( $server_response) ) {
// do something to handle error
} else {
// PASS OUR PDF to the user
$response_body = wp_remote_retrieve_body( $server_response);
header("Content-type: application/pdf");
header("Content-disposition: attachment;filename=downloaded.pdf");
echo $response_body;
}
} else {
get_header();
$html = "<div class='content-container'><p>A pretty error message here.</p></div>";
echo $html;
get_footer();
}
?>
The approach is essentially to pass the result from the API straight back out the user, but you need the headers to specific it's a PDF, and the headers have to be set before you write out any output. An easier way to ensure this was to do it in a new window, rather than strictly on the form postback.

Related

How to notify through email in wordpress

How to notify through email in wordpress when visitor clicks on a link that this link was pressed and/or user ip, city and country was this?
I have given the link a class 'email-link'.
something like this should get you started
// functions.php
// HTML form markup
function mail_form_stuff() {
echo '<form action="' . esc_url( $_SERVER['REQUEST_URI'] ) . '" method="post">';
echo '<p><input type="submit" name="send_the_email_to_admin" value="Click this button"></p>';
echo '</form>';
}
// make sure the email will allow for html -- not just plain text
add_filter( 'wp_mail_content_type', 'send_the_email_to_admin_content_type' );
function send_the_email_to_admin_content_type() {
return 'text/html';
}
// if the button is clicked, send the email
function deliver_mail_link_stuff() {
$admin_email = get_option( 'admin_email' );
if ( isset($_POST["send_the_email_to_admin"]) ) {
$_user = wp_get_current_user();
$_name = esc_html( $_user->user_firstname );
$_email = esc_html( $_user->user_email );
$to = $admin_email;
$subject = "Some person clicked my link";
$message = 'Hey this person clicked on that button'.'<br>';
$message .= "the persons email address was: $_email";
$headers[] = "From: $_name <$_email>" . "\r\n";
// $headers[] = "Bcc: John Smith <jsmith#gmail.com>" . "\r\n";
// If everything worked -- display a success message
if ( wp_mail( $to, $subject, $message, $headers ) ) {
echo '<p>sent</p>';
} else {
echo 'An unexpected error occurred';
}
// reset wp_mail_content_type
remove_filter( 'wp_mail_content_type', 'send_the_email_to_admin_content_type' );
}
}
function add_short_code_stuff() {
ob_start();
deliver_mail_link_stuff();
mail_form_stuff();
return ob_get_clean();
}
add_shortcode( 'EMAIL_BUTTON', 'add_short_code_stuff' );
this will add a short code for you
you can then call the shortcode in your theme with
echo do_shortcode('[EMAIL_BUTTON]');
You can't do this as a direct consequence of WordPress since a link is HTML and has no correlation to or integration with anything controlled or processed directly by WordPress. WordPress is merely a structure/processes through which you can add info to a database and then later retrieve it.
If you question is actually meant in a more generic and not specifically wordPress sense, then the answer is any number of ways. You could for example create some JQuery or JS that would add that info everytime a link was clicked. But, you would need to interact with the page headers to try and get all the required info.
But, why bother doing that when a free & arguably market leading tool that does this is already available?
The logical process to this is to use Google Analytics (or a rival tool) as this already collects this kind of info with very little work required to set it up. If you want more specific "event" triggered data (eg a link is clicked), then you can also do this fairly easily too.
https://analytics.google.com
UPDATE
In your comment, you clarify that you want a real time email to be sent to you when a link is clicked, and thus analytics isn't going to fit the bill. In that case you will need to do some work using JQuery & AJAX.
In simple terms you'll need to do something this:
1) Create some JQuery to intercept the url of the link clicked
2) Pass the link (and header info) to a function via an AJAX call
3) Process the header data / send the email
4) Redirect user to the url passed from the link
Here's a tutorial on creating a simple AJAX process in WordPress: https://www.makeuseof.com/tag/tutorial-ajax-wordpress/

Loading views_accordion through an ajax request

I am currently loading my view through an ajax request in my custom module:
$.getJSON('/reports/summarized-progress/get_output_activities/'+nid, null,activities);
The drupal page for the above request returns the following:
$output_arg=arg(3);
$html="";
$activities=views_embed_view('activities','block_activities',$output_arg); //this returns a view accordion view
if(!empty($activities)) {
$html.='';
$html.=$activities;
$html.='';
}
drupal_json_output(array('data'=>$html));
The accordion/collapsible functionality is not working on the loaded content. Any ideas whether I need to include through module_load_include any files in my custom module? What needs to be done for this to work?
Whenever you load content through ajax request, you have to ensure that the needed js settings/files are loaded along with your content.
In most cases, the $javascript static variable that is filled during a content load through drupal_add_js() is not sent to the browser, but you can do this manually :
Here a working Drupal 6 example :
// Get the view content.
$view = views_embed_view($name, $display_id);
// Get javascript data.
$js = drupal_add_js(NULL, NULL, 'header');
// Prepare data to be processed clientside.
$settings = drupal_to_js(call_user_func_array('array_merge_recursive', $js['setting']));
// Tell the client to extend Drupal.settings with collected $settings.
$script = '<script type="text/javascript">
jQuery.extend(true, Drupal.settings, ' . $settings . ');
</script>';
drupal_set_header('Content-Type:text/html; charset=utf-8');
print $script . $view;
exit;
Same in Drupal 7 :
$view = views_embed_view($name, $display_id);
$js = drupal_add_js(NULL, array('type' => 'setting'));
$settings = drupal_json_encode(call_user_func_array('array_merge_recursive', $js['settings']['data']));
$script = '<script type="text/javascript">
jQuery.extend(true, Drupal.settings, ' . $settings . ');
</script>';
drupal_add_http_header('Content-Type', 'text/html; charset=utf-8');
print $script . $view;
exit;
Note :
If your accordion view rely on a specific .js file, ensure this file is sourced inside every page where ajax requests take place. Usually, you'll have to explicitly source this file if such a page is loaded (full page load) without the view.
You can achieve this in a hook_page_preprocess() implementation :
function moduleName_preprocess_page(&$variables) {
// Include .js to the page so views can rely on in future ajax request
drupal_add_library('system', 'ui.accordion');
drupal_add_js(drupal_get_path('module', 'views_accordion') . '/views-accordion.js');
// Add the css for fixing/preventing accordion issues.
drupal_add_css(drupal_get_path('module', 'views_accordion') . '/views-accordion.css');
// ...
}
... or by including the file when the content is requested (as we do for Drupal.settings), just add a script tag in the $script variable in the ajax callback :
$script .= '<script type="text/javascript" src="sourcefile.js"></script>'
Hope this helps!

How can I style the WordPress failure notice page?

Is there a way I can style the WordPress failure notice page? Take a look at the screenshot below which shows an example of the page. This page is generated at various times and for various reasons. To generate the page, open 2 tabs in your browser and login to the same WordPress site on each tab.
1: log out of the site via the first tab you have open.
2: log out via the second tab.
You'll see the failure page.
The approach I took was to set up a custom die handler which gives you the option to style all 'die' messages.
// custom die handler
function get_custom_die_handler() {
return 'custom_die_handler';
}
// hook the function
add_filter('wp_die_handler', 'get_custom_die_handler' );
// build a custom die handler
function custom_die_handler( $message, $title = '', $args = array() ) {
// whatever you want the die handler to do
}
Navigate to the file /wp-includes/functions.php look for a function called
wp_nonce_ays
That is the function which outputs the error page. That is a core function, which is called by the action of check_admin_referer. You could try to hook into that action; the only problem is that it dies after wp_nonce_ays is called, so using add_action has no effect since it dies before it would trigger. However, luckily, check_admin_referer is a pluggable function, so you can make a function to override it. Our function will be an exact copy of check_admin_referer except one extra line of code is added to style it. Save the function, I called it styleFailPage.php, and put it in your /wp-content/plugins/ folder.
<?php /*
* Plugin Name:Failure Styler
* Description:Adds a style element right before the failure notice is called
*/
if ( ! function_exists( 'wp_logout' ) ) {
function check_admin_referer($action = -1, $query_arg = '_wpnonce') {
if ( -1 == $action )
_doing_it_wrong( __FUNCTION__, __( 'You should specify a nonce action to be verified by using the first parameter.' ), '3.2' );
$adminurl = strtolower(admin_url());
$referer = strtolower(wp_get_referer());
$result = isset($_REQUEST[$query_arg]) ? wp_verify_nonce($_REQUEST[$query_arg], $action) : false;
if ( !$result && !(-1 == $action && strpos($referer, $adminurl) === 0) ) {
//this is the line I added:
echo "<style>body {background:red !important;}</style>";
wp_nonce_ays($action);
die();
}
do_action('check_admin_referer', $action, $result);
return $result;
}
}
?>
This will make invalid HTML because you have to end up inserting the <style> info ABOVE the doctype declaration, however AFAIK this is unavoidable without explicitly editing the core wp_nonce_ays function

Wordpress - using php to redirect to a different page

I am trying to create a form that when submitted, adds data to a mysql database and redirects to a success page.
I added this code to the bottom of my functions.php file:
add_action('init', 'form_submit');
function form_submit(){
global $wpdb;
if(isset($_POST['form_sub']))
{
$name= $_POST['name'];
$age= $_POST['age'];
$wpdb->insert(
'mytable',
array(
'name' => $name,
'age' => $age
),
array(
'%s',
'%s'
)
);
header("Location: http://www.google.com");
}
}
and added a form to my page that calls this function when submit is clicked.
When I try this, the data is added to the mysql database, but the redirect doesn't seem to work. Instead of going to google.com, it adds this to the top of the page:
Object Moved
This document may be found here
Where here is a link to google.com. Any idea on how to fix this? Thank you!
You are probably sending the redirect header too late (after the page is rendered).
Check this out: http://shibashake.com/wordpress-theme/wordpress-page-redirect
You can try to put out a javascript redirect if you can't get the header() or wp_redirect() out early enough.

need the right way to setcookie in wordpress

i've been looking the whole day how to setcookies in wordpress. in my way i found out (using the developer toolbar) that the cookie is set but still not working.
i have 2 files the first contains the login form redirecting to another page to set the cookie and return to another page to check if it's working. domain which is tested on is like this : blog.mydomain.com. here's the setcookie file :
<?php
setcookie("user_name","test",time()+3600);
?>
and chcking the cookie like this :
if(isset($_COOKIE["user_name"])){
echo "cookie exists";
}
else{
echo "cookie doesn't exist";
}
i've read many topics about this issue but there was no clear answer.
Thanks in advance
This typically happens when you try to set a cookie after sending output to the browser. To set a cookie in WP, you should use the 'init' hook to set the cookie on init.
function set_username_cookie() {
if (!isset($_COOKIE['user_name'])) {
setcookie("user_name","test",time()+3600);
}
}
add_action( 'init', 'set_username_cookie');
well, my best way to use cookie in wordpress is this,
function set_my_cookie() {
global $post;
$post_id = $post->ID;
$cookie_name = "my_cookie";
$cookie_value = "my_cookie_val";
if (!isset($_COOKIE['my_cookie'])) {
{
setcookie($cookie_name, $cookie_value, time() + (86400 * 30), "/");
}}add_action( 'wp', 'set_my_cookie');
i used this the function to setcookie in wp hook of wordpress. the main reason of this is that we may need sometime current page or post, that we cannot access on init hook, but we can access in wp hook.
now, in a shortcode or other plugin/theme functions we may just need to check if the cookie exists or not. thats it
Another option is to use PHP's ob_start(); and ob_end_flush();.
You can find documentation on the two functions here
The way I resolved my issues was to call the two functions before and after the opening and closing html tags like this:
<?php ob_start(); ?>
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<?php /* Wordpress loop and other tempate code here */ ?>
</body>
</html>
<?php ob_end_flush(); ?>
The issue I was running into was calling a global function that used PHP's setcookie(); and because WordPress processes the page progressively, the cookie couldn't be created due to the page's headers already being sent.
PHP's output buffering function forces the headers to be sent before WordPress processes the page.
Hope this helps.

Resources