<?php
/*
Plugin Name: WP Post to PDF
Plugin URI: http://www.vareen.co.cc
Description: Allow visitor to download post in PDF format. No addon or change required on server. Uses TCPDF class to generate PDF. Click 'Settings' link to configure plugin.
Version: 2.0
License: GPL
Author: Neerav Dobaria
Author URI: http://www.vareen.co.cc
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//avoid direct calls to this file, because now WP core and framework has been used
if (!function_exists('add_action')) {
header('Status: 403 Forbidden');
header('HTTP/1.1 403 Forbidden');
exit();
}
// Define certain terms which may be required throughout the plugin
global $blog_id;
define('WPPT0PDF_NAME', 'WP Post to PDF');
define('WPPT0PDF_SNAME', 'wpptopdf');
define('WPPT0PDF_PATH', WP_PLUGIN_DIR . '/wp-post-to-pdf');
define('WPPT0PDF_URL', WP_PLUGIN_URL . '/wp-post-to-pdf');
define('WPPT0PDF_BASENAME', plugin_basename(__FILE__));
define('WPPT0PDF_CACHE_DIR', WP_CONTENT_DIR . '/uploads/wp-post-to-pdf-cache/'.$blog_id);
if (!class_exists(wpptopdf)) {
class wpptopdf {
private $options;
function wpptopdf() {
$this->options = get_option('wpptopdf');
if (is_admin()) {
add_action('admin_init', array(&$this, 'on_admin_init'));
add_action('admin_menu', array(&$this, 'on_admin_menu'));
add_filter("plugin_action_links_" . WPPT0PDF_BASENAME, array(&$this, 'action_links'));
register_activation_hook(WPPT0PDF_BASENAME, array(&$this, 'on_activate'));
add_action('pre_post_update', array(&$this, 'on_pre_post_update'));
add_action('post_updated', array(&$this, 'generate_pdf_file'));
} else {
add_action('wp', array(&$this, 'generate_pdf'));
add_filter('the_content', array(&$this, 'add_button'));
}
}
function on_admin_init() {
register_setting('wpptopdf_options', 'wpptopdf', array(&$this, 'on_update_options'));
}
function on_update_options($post) {
if (isset($post['submit']) and 'Save and Reset PDF Cache' == $post['submit']) {
$this->delete_cache(WPPT0PDF_CACHE_DIR);
}
return $post;
}
function delete_cache($path) {
if (is_dir($path) === true) {
$files = array_diff(scandir($path), array('.', '..'));
foreach ($files as $file) {
$this->delete_cache(realpath($path) . '/' . $file);
}
return true;
}
else if (is_file($path) === true) {
return unlink($path);
}
return false;
}
function on_admin_menu() {
$option_page = add_options_page('WP Post to PDF Options', 'WP Post to PDF', 'administrator', WPPT0PDF_BASENAME, array(&$this, 'options_page'));
//add_action("admin_print_scripts-$option_page", array(&$this, 'on_admin_print_scripts'));
add_action("admin_print_styles-$option_page", array(&$this, 'on_admin_print_styles'));
}
function options_page() {
include(WPPT0PDF_PATH . '/wpptopdf_options.php');
}
function on_admin_print_styles() {
wp_enqueue_style('wpptopdfadminstyle', WPPT0PDF_URL . '/asset/css/admin.css', false, '1.0', 'all');
}
/*function on_admin_print_scripts() {
wp_enqueue_script('wpptopdfadminstyle', WPPT0PDF_URL . '/asset/css/admin.css',false, '1.0', 'all');
}*/
function action_links($links) {
$settings_link = '<a href="options-general.php?page=' . WPPT0PDF_BASENAME . '">Settings</a>';
array_unshift($links, $settings_link);
return $links;
}
function generate_pdf() {
if ('pdf' == $_GET['format']) {
if ($this->options['nonPublic'] and !is_user_logged_in())
return false;
global $post;
$include = $this->options['include'];
$excludeThis = explode(',', $this->options['excludeThis']);
if ($include and !in_array($post->ID, $excludeThis))
return false;
if (!$include and in_array($post->ID, $excludeThis))
return false;
$filePath = WPPT0PDF_CACHE_DIR . '/' . $post->post_name . '.pdf';
$fileMime = 'pdf';
$fileName = $post->post_name . '.pdf';
if (!file_exists($filePath)) {
$this->generate_pdf_file($post->ID);
}
$output = $this->output_pdf_file($filePath, $fileName, $fileMime);
}
}
function output_pdf_file($file, $name, $mime_type = '') {
if (!is_readable($file))
return false;
$size = filesize($file);
$name = rawurldecode($name);
/* Figure out the MIME type (if not specified) */
$known_mime_types = array(
"pdf" => "application/pdf",
"txt" => "text/plain",
"html" => "text/html",
"htm" => "text/html",
"exe" => "application/octet-stream",
"zip" => "application/zip",
"doc" => "application/msword",
"xls" => "application/vnd.ms-excel",
"ppt" => "application/vnd.ms-powerpoint",
"gif" => "image/gif",
"png" => "image/png",
"jpeg" => "image/jpg",
"jpg" => "image/jpg",
"php" => "text/plain"
);
if ($mime_type == '') {
$file_extension = strtolower(substr(strrchr($file, "."), 1));
if (array_key_exists($file_extension, $known_mime_types)) {
$mime_type = $known_mime_types[$file_extension];
} else {
$mime_type = "application/force-download";
}
}
@ob_end_clean(); //turn off output buffering to decrease cpu usage
// required for IE, otherwise Content-Disposition may be ignored
if (ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');
header('Content-Type: ' . $mime_type);
header('Content-Disposition: attachment; filename="' . $name . '"');
header("Content-Transfer-Encoding: binary");
header('Accept-Ranges: bytes');
/* The three lines below basically make the
download non-cacheable */
header("Cache-control: private");
header('Pragma: private');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
// multipart-download and download resuming support
if (isset($_SERVER['HTTP_RANGE'])) {
list($a, $range) = explode("=", $_SERVER['HTTP_RANGE'], 2);
list($range) = explode(",", $range, 2);
list($range, $range_end) = explode("-", $range);
$range = intval($range);
if (!$range_end) {
$range_end = $size - 1;
} else {
$range_end = intval($range_end);
}
$new_length = $range_end - $range + 1;
header("HTTP/1.1 206 Partial Content");
header("Content-Length: $new_length");
header("Content-Range: bytes $range-$range_end/$size");
} else {
$new_length = $size;
header("Content-Length: " . $size);
}
/* output the file itself */
$chunksize = 1 * (1024 * 1024); //you may want to change this
$bytes_send = 0;
if ($file = fopen($file, 'r')) {
if (isset($_SERVER['HTTP_RANGE']))
fseek($file, $range);
while (!feof($file) &&
(!connection_aborted()) &&
($bytes_send < $new_length)
) {
$buffer = fread($file, $chunksize);
print($buffer); //echo($buffer); // is also possible
flush();
$bytes_send += strlen($buffer);
}
fclose($file);
} else
return false;
return true;
}
function generate_pdf_file($id, $forceDownload = false) {
$post = get_post($id);
if ('post' != $post->post_type and 'page' != $post->post_type)
return false;
require_once(WPPT0PDF_PATH . '/tcpdf/config/lang/eng.php');
require_once(WPPT0PDF_PATH . '/tcpdf/tcpdf.php');
$filePath = WPPT0PDF_CACHE_DIR . '/' . $post->post_name . '.pdf';
// create new PDF document
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
// Let other filter modify content if selected
if ($this->options['otherPlugin'])
$post->post_content = apply_filters('the_content', $post->post_content);
// Process shortcodes if selected
if ($this->options['processShortcodes'])
$post->post_content = do_shortcode($post->post_content);
// set document information
$pdf->SetCreator('WP Post to PDF plugin by Neerav Dobaria (http://www.vareen.co.cc) along with ' . PDF_CREATOR);
$pdf->SetAuthor(get_bloginfo('name'));
$pdf->SetTitle($post->post_title);
// Count width of logo for better presentation
$logodata = getimagesize(PDF_HEADER_LOGO);
$logowidth = (int) ((14 * $logodata[0]) / $logodata[1]);
//$pdf->SetSubject('TCPDF Tutorial');
//$pdf->SetKeywords('TCPDF, PDF, example, test, guide');
// set default header data
$pdf->SetHeaderData(PDF_HEADER_LOGO, $logowidth, html_entity_decode(get_bloginfo('name')), html_entity_decode(get_bloginfo('description') . "\n" . get_bloginfo('siteurl')));
// set header and footer fonts
$pdf->setHeaderFont(Array($this->options['headerFont'], '', $this->options['headerFontSize']));
$pdf->setFooterFont(Array($this->options['footerFont'], '', $this->options['footerFontSize']));
// set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
//set margins
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
//set auto page breaks
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
//set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
//set some language-dependent strings
$pdf->setLanguageArray($l);
// ---------------------------------------------------------
// set default font subsetting mode
$pdf->setFontSubsetting(true);
// Set font
// dejavusans is a UTF-8 Unicode font, if you only need to
// print standard ASCII chars, you can use core fonts like
// helvetica or times to reduce file size.
$pdf->SetFont($this->options['contentFont'], '', $this->options['contentFontSize'], '', true);
// Add a page
// This method has several options, check the source code documentation for more information.
$pdf->AddPage();
// Set some content to print
$html = '<h1>' . html_entity_decode($post->post_title, ENT_QUOTES) . '</h1>';
$html .= html_entity_decode($post->post_content, ENT_QUOTES);
// Print text using writeHTML
$pdf->writeHTML($html, true, 0, true, 0);
// ---------------------------------------------------------
// Close and output PDF document
// This method has several options, check the source code documentation for more information.
// Create directory if not exist
if(!is_dir(WPPT0PDF_CACHE_DIR))
mkdir(WPPT0PDF_CACHE_DIR);
if ($forceDownload)
$pdf->Output($filePath, 'FI');
else
$pdf->Output($filePath, 'F');
}
function add_button($content) {
// If manual is selected, let user decide where to add button
if ('manual' == $this->options['iconPosition'])
return $content;
// get button html
$button = $this->display_icon();
// Set button after and before post
if ('beforeandafter' == $this->options['iconPosition'])
$content = $button . $content . $button;
// Set button after post
elseif ('after' == $this->options['iconPosition'])
$content = $content . $button;
// by default Set button before post
else
$content = $button . $content;
return $content;
}
function display_icon() {
// return nothing if no permission
if ($this->options['nonPublic'] and !is_user_logged_in())
return;
if ($this->options['onSingle'] and !(is_single() or is_page()))
return;
global $post;
// return nothing if post in exclude list
$include = $this->options['include'];
$excludeThis = explode(',', $this->options['excludeThis']);
if ($include and !in_array($post->ID, $excludeThis))
return;
if (!$include and in_array($post->ID, $excludeThis))
return;
// Change querystring separator for those who do not have pretty URL enabled
$qst = get_permalink($post->ID);
$qst = parse_url($qst);
if ($qst['query'])
$qst = '&format=pdf';
else
$qst = '?format=pdf';
return '<a class="wpptopdf" target="_blank" rel="noindex,nofollow" href="' . get_permalink($post->ID) . $qst . '" title="Download PDF">' . $this->options['imageIcon'] . '</a>';
}
function on_activate() {
if (!file_exists(WP_CONTENT_DIR . '/uploads/wp-post-to-pdf-logo.png'))
copy(WPPT0PDF_PATH . '/asset/images/logo.png', WP_CONTENT_DIR . '/uploads/wp-post-to-pdf-logo.png');
if (!is_dir(WP_CONTENT_DIR . '/uploads/wp-post-to-pdf-cache'))
mkdir(WP_CONTENT_DIR . '/uploads/wp-post-to-pdf-cache');
}
function on_pre_post_update($id) {
$post = get_post($id);
$filePath = WPPT0PDF_CACHE_DIR . '/' . $post->post_name . '.pdf';
if (file_exists($filePath))
unlink($filePath);
}
}
$wpptopdf = new wpptopdf();
/**
* Display PDF download icon if applicable
* @return void
*/
function wpptopdf_display_icon() {
global $wpptopdf;
//$wpptopdf = new wpptopdf();
return $wpptopdf->display_icon();
}
}