PluginProbe
Print, PDF & Email by PrintFriendly / 3.11.0
Print, PDF & Email by PrintFriendly v3.11.0
5.5.13 5.5.12 5.5.11 trunk 0.2 0.9 1.0 2.0 2.1.8 3.0 3.0.9 3.1.6 3.10.0 3.11.0 3.11.1 3.11.2 3.12.0 3.12.1 3.12.2 3.12.3 3.12.4 3.12.5 3.13.0 3.14.0 3.14.1 All 95 releases
printfriendly / pf.php

pf.php in Print, PDF & Email by PrintFriendly 3.11.0, at pf.php

1,626 lines 68.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 Plugin Name: Print, PDF & Email by PrintFriendly
5 Plugin URI: http://www.printfriendly.com
6 Description: PrintFriendly & PDF button for your website. Optimizes your pages and brand for print, pdf, and email.
7 Name and URL are included to ensure repeat visitors and new visitors when printed versions are shared.
8 Version: 3.11.0
9 Author: Print, PDF, & Email by PrintFriendly
10 Author URI: http://www.PrintFriendly.com
11
12 Changelog :
13 3.11.0 - Update buttons
14 3.10.0 - Change "leave us a rating" message.
15 3.9.2 - Correctly handle spaces in print-only detection
16 3.9.1 - Better print-only detection
17 3.9.0 - Add new button
18 3.8.7 - Bug fix.
19 3.8.6 - Allow default image setting to be small medium or large.
20 3.8.5 - Bug fix.
21 3.8.4 - Bug fix.
22 3.8.1 - Improve automatic error reporting.
23 3.8.0 - Add automatic error reporting.
24 3.7.6 - WooCommerce support improvments: remove upsells from print preview.
25 3.7.5 - WooCommerce support improvments: fix DOMDocument.loadHTML warnings.
26 3.7.4 - Added CSS Relative Position and Z-Index to button to avoid content covering the button.
27 3.7.3 - Always use https
28 3.7.2 - Use schema less URLs for loading icons
29 3.7.1 - Use www.printfriendly.com instead of app.printfriendly.com for redirects
30 3.7.0 - Remove http/https option, use current schema
31 3.6.0 - Allow custom HTML in Custom Button Text
32 3.5.4 - WooCommerce 'Content Algorithm' fix
33 3.5.3 - Fix security issues
34 3.5.2 - Fix code to support PHP 5.2
35 3.5.0 - WooCommerce product page improvements. Better support for product images, price, and description.
36 3.4.8 - Fix button images style
37 3.4.7 - Fix button style to remove underline
38 3.4.6 - Always removed PrintFriendly button underline regardless plugin CSS for button styles option
39 3.4.4 - Removed page content selection option - Wordpress Standard/Strict
40 3.4.2 - Fixed the issue occured due to new changes made in the page content selection options
41 3.4.1 - Improved page content selection options
42 3.4.0 - Fixed the admin javascript error and increased plugin text boxes size
43 3.3.10 - Implemented both Classic Google Analytics and Google Universal Analytics code.
44 3.3.9 - Removed the functionality that opens new window when JavaScript is disabled.
45 3.3.8 - Shortcode Bug fix, urlencode button href
46 3.3.7 - Readme.txt update
47 3.3.6 - Fixed JS optimization Bug
48 3.3.5 - Wordpress 3.8 support
49 3.3.4 - Provided Algorithm Options
50 3.3.3 - Using WP content hook for all Buttons
51 3.3.2 - Algorithm update
52 3.3.1 - SSL support issue.
53 3.3.0 - Printfriendly custom commands support and PF Algo V6 release.
54 3.2.10 - Fixed Bug.
55 3.2.9 - Added Support for Google Analytics
56 3.2.8 - Algorithm Update
57 3.2.7 - Removed Break tag from button code.
58 3.2.6 - Fixed Button behavior when displayed on Homepage for NON-JS version. Fixed CSS issue with Button when placed above content. Fixed box-shadow issue with button. Custom print and pdf options now available for Non-JS version (custom header, custom css, image alignment, etc.). Fixed custom header bug.
59 3.2.5 - Added hide images and image style options. Improved input validation. Improved output escaping. Removed printfriendly post_class. Small i8n fix. Few small HTML fixes.
60 3.2.4 - Add printfriendly post_class. Fixed minor JS bug. Added redundancy to uninstall script.
61 3.2.3 - Rolling back to version 3.2.1
62 3.2.2 - Add printfriendly post_class. Add printfriendly button display settings per individual category. Fixed minor JS bug. Added redundancy to uninstall script.
63 3.2.1 - Improve script loading.
64 3.2.0 - Important chrome issue fix. Ie syntax error fix.
65 3.1.9 - Minor css detail.
66 3.1.8 - Add printfriendly options to allow/not allow print, pdf, email from the Printfriendly and PDF dialog.
67 3.1.7 - Revert default print button show settings. Prevent easy override of print button text-decoration and border style properties.
68 3.1.6 - Adding PrintFriendly and PDF alignment style classes.
69 3.1.5 - Set button appearance in more flexible way. Remove styles that interfered with wordpress themes. Add shortcode for printfriendly button. Fix redirect to printfriendly.com link. Added custom css feature.
70 3.1.4 - Changed https url. Don't hide text change box when disabling css.
71 3.1.3 - Fixed bug with disable css option
72 3.1.2 - Added disable css option to admin settings.
73 3.1.1 - Fixed admin js caching.
74 3.1.0 - Fixed admin css caching.
75 3.0.9 - New features: Custom header, disable click-to-delete, https support (beta), PrintFriendly Pro (ad-free).
76 3.0.8 - Reordered PrintFriendly & PDF buttons. CSS stylesheet option is now checked by default.
77 3.0.7 - Added additional images for print button.
78 3.0.6 - Fix bug that would display button on category pages when not wanted.
79 3.0.5 - Include button on category pages if user has selected "All pages".
80 3.0.4 - Align-right and align-center support for themes that remove WordPress core css.
81 3.0.3 - Support for bad themes that alter template tags and prevent JavaScript from loading in footer.
82 3.0.2 - Fixed JS bug with Google Chrome not submitting and fixed input validation issues.
83 3.0.1 - Fixed minor JS bug.
84 3.0 - Complete overhaul of the plugin by Joost de Valk.
85 2.1.8 - The Print Button was showing up on printed, or PDF, pages. Junk! Print or PDF button no longer displayed on printed out page or PDF.
86 2.1.7 - Changed button from span to div to support floating.
87 2.1.6 - Added rel="nofollow" to links. Changed button from <a> to <span> to fix target_new or target_blank issues.
88 2.1.5 - Fix conflict with link tracking plugins. Custom image support for hosted wordpress sites.
89 2.1.4 - wp head fix.
90 2.1.3 - Manual option for button placement. Security updates for multi-author sites.
91 2.1.2 - Improvements to Setting page layout and PrintFriendly button launching from post pages.
92 2.1.1 - Fixed admin settings bug.
93 2.1 - Update for mult-author websites. Improvements to Settings page.
94 2.0 - Customize the style, placement, and pages your printfriendly button appears.
95 1.5 - Added developer ability to disable hook and use the pf_show_link() function to better be used in a custom theme & Uninstall cleanup.
96 1.4 - Changed Name.
97 1.3 - Added new buttons, removed redundant code.
98 1.2 - User can choose to show or not show buttons on the listing page.
99 */
100
101 /**
102 * PrintFriendly WordPress plugin. Allows easy embedding of printfriendly.com buttons.
103 * @package PrintFriendly_WordPress
104 * @author PrintFriendly <support@printfriendly.com>
105 * @copyright Copyright (C) 2012, PrintFriendly
106 */
107 if ( ! class_exists( 'PrintFriendly_WordPress' ) ) {
108
109 /**
110 * Class containing all the plugins functionality.
111 * @package PrintFriendly_WordPress
112 */
113 class PrintFriendly_WordPress {
114 /**
115 * Current plugin version.
116 * @var string
117 */
118 var $plugin_version = '3.11.0';
119
120 /**
121 * The hook, used for text domain as well as hooks on pages and in get requests for admin.
122 * @var string
123 */
124 var $hook = 'printfriendly';
125
126 /**
127 * The option name, used throughout to refer to the plugins option and option group.
128 * @var string
129 */
130 var $option_name = 'printfriendly_option';
131
132 /**
133 * The plugins options, loaded on init containing all the plugins settings.
134 * @var array
135 */
136 var $options = array();
137
138 /**
139 * Database version, used to allow for easy upgrades to / additions in plugin options between plugin versions.
140 * @var int
141 */
142 var $db_version = 13;
143
144 /**
145 * Settings page, used within the plugin to reliably load the plugins admin JS and CSS files only on the admin page.
146 * @var string
147 */
148 var $settings_page = '';
149
150 /**
151 * GetSentry error reporting client
152 * @var Raven_Client
153 */
154 var $raven_client = null;
155
156 /**
157 * Constructor
158 *
159 * @since 3.0
160 */
161 function __construct() {
162 try {
163 // delete_option( $this->option_name );
164
165 // Retrieve the plugin options
166 $this->options = get_option( $this->option_name );
167
168 // If the options array is empty, set defaults
169 if ( ! is_array( $this->options ) )
170 $this->set_defaults();
171
172 // Sentry PHP SDK supports PHP 5.3 and higher.
173 if( isset( $this->options['enable_error_reporting'] ) && $this->options['enable_error_reporting'] == 'yes' && version_compare(PHP_VERSION, '5.3.0') >= 0) {
174 $this->init_error_reporting();
175 }
176
177 /**
178 * Set page content selection option "Wordpress Standard/Strict" to "WP Template"
179 */
180 if( isset( $this->options['pf_algo'] ) && $this->options['pf_algo'] == 'ws' ){
181 $this->options['pf_algo'] = 'wp';
182 update_option( $this->option_name, $this->options );
183 }
184
185 // If the version number doesn't match, upgrade
186 if ( $this->db_version > $this->options['db_version'] )
187 $this->upgrade();
188
189 add_action( 'wp_head', array( &$this, 'front_head' ) );
190 // automaticaly add the link
191 if( !$this->is_manual() ) {
192 add_filter( 'the_content', array( &$this, 'show_link' ) );
193 add_filter( 'the_excerpt', array( &$this, 'show_link' ) );
194 }
195
196 add_action('the_content', array(&$this, 'add_pf_content_class_around_content_hook'));
197
198 // Admin hooks
199 if ( is_admin() ) {
200 // Hook into init for registration of the option and the language files
201 add_action( 'admin_init', array( &$this, 'init' ) );
202
203 // Register the settings page
204 add_action( 'admin_menu', array( &$this, 'add_config_page' ) );
205
206 // Register the contextual help
207 add_filter( 'contextual_help', array( &$this, 'contextual_help' ), 10, 2 );
208
209 // Enqueue the needed scripts and styles
210 add_action( 'admin_enqueue_scripts',array( &$this, 'admin_enqueue_scripts' ) );
211
212 // Register a link to the settings page on the plugins overview page
213 add_filter( 'plugin_action_links', array( &$this, 'filter_plugin_actions' ), 10, 2 );
214 }
215 } catch(Exception $e) {
216 $this->raven_catch($e);
217 }
218 }
219
220 function init_error_reporting() {
221 try {
222 require_once 'vendor/PrintFriendly/Raven/Autoloader.php';
223
224 PrintFriendly_Raven_Autoloader::register();
225
226 $this->raven_client = new PrintFriendly_Raven_Client('https://46a55182ffbe477c8cf1cb0f1cee36c2:a32ee5b4fad940c4808845b618147f21@sentry.io/171161', array(
227 'release' => $this->plugin_version,
228 'timeout' => 4
229 ));
230
231 $this->raven_client->tags_context(array(
232 'wordpress-version' => get_bloginfo('version'),
233 'php-version' => PHP_VERSION
234 ));
235
236 $this->raven_client->setSendCallback(array( &$this, 'raven_callback' ));
237 } catch (Exception $e) {
238 if (!ini_get('display_errors')) {
239 error_log('PrintFriendly init_error_reporting Error: ' . $e);
240 }
241
242 $this->raven_catch($e);
243 }
244 }
245
246 function raven_callback($data) {
247 try {
248 return isset($data) && preg_match('/printfriendly/', json_encode($data));
249 } catch (Exception $e) {
250 return true;
251 }
252 }
253
254 function raven_catch($e) {
255 if (isset($this->raven_client)) {
256 try {
257 $this->raven_client->captureException($e);
258 } catch(Exception $e) {}
259 }
260 }
261
262 /**
263 * Adds wraps content in pf-content class to help Printfriendly algo determine the content
264 *
265 * @since 3.2.8
266 *
267 **/
268 function add_pf_content_class_around_content_hook($content = false) {
269 try {
270 if( $this->is_wp_algo_on($content) ) {
271 add_action( 'wp_footer', array( &$this, 'print_script_footer' ));
272 return '<div class="pf-content">'.$content.'</div>';
273 } else {
274 return $content;
275 }
276 } catch (Exception $e) {
277 $this->raven_catch($e);
278 }
279 }
280
281 /**
282 * Override to check if print-only command is being used
283 *
284 * @since 3.3.0
285 **/
286 function print_only_override($content) {
287 $pattern = '/class\s*?=\s*?(["\']|["\']([^"\']*?)\s)print-only(["\']|\s([^"\']*?)["\'])/';
288 $pf_pattern = '/class\s*?=\s*?(["\']|["\']([^"\']*?)\s)pf-content(["\']|\s([^"\']*?)["\'])/';
289
290 return (preg_match($pattern, $content) || preg_match($pf_pattern, $content)) ;
291 }
292
293 /**
294 * Check if WP Algorithm is selected and content doesn't use print-only
295 *
296 * @since 3.5.4
297 **/
298 function is_wp_algo_on($content) {
299 return !class_exists('WooCommerce') && isset($this->options['pf_algo']) && $content && $this->options['pf_algo'] == 'wp' && !$this->print_only_override($content);
300 }
301
302 /**
303 * PHP 4 Compatible Constructor
304 *
305 * @since 3.0
306 */
307 function PrintFriendly_WordPress() {
308 $this->__construct();
309 }
310
311 /**
312 * Prints the PrintFriendly button CSS, in the header.
313 *
314 * @since 3.0
315 */
316 function front_head() {
317 try {
318 ?>
319 <style type="text/css" media="screen">
320 div.printfriendly a, div.printfriendly a:link, div.printfriendly a:hover, div.printfriendly a:visited {
321 text-decoration: none;
322 border: none;
323 }
324 </style>
325 <?php
326
327 if ( isset( $this->options['enable_css'] ) && $this->options['enable_css'] != 'on' )
328 return;
329 ?>
330 <style type="text/css" media="screen">
331 div.printfriendly {
332 margin: <?php echo $this->options['margin_top'].'px '.$this->options['margin_right'].'px '.$this->options['margin_bottom'].'px '.$this->options['margin_left'].'px'; ?>;
333 position: relative;
334 z-index: 1000;
335 }
336 div.printfriendly a, div.printfriendly a:link, div.printfriendly a:visited {
337 font-size: <?php echo $this->options['text_size']; ?>px;
338 color: <?php echo $this->options['text_color']; ?>;
339 vertical-align: bottom;
340 }
341 .printfriendly a {
342 box-shadow:none;
343 }
344 .printfriendly a:hover {
345 cursor: pointer;
346 }
347 .printfriendly a img {
348 border: none;
349 padding:0;
350 margin-right: 6px;
351 box-shadow: none;
352 -webkit-box-shadow: none;
353 -moz-box-shadow: none;
354 }
355 .printfriendly a span{
356 vertical-align: bottom;
357 }
358 .pf-alignleft {
359 float: left;
360 }
361 .pf-alignright {
362 float: right;
363 }
364 div.pf-aligncenter {
365 display: block;
366 margin-left: auto;
367 margin-right: auto;
368 text-align: center;
369 }
370 </style>
371 <style type="text/css" media="print">
372 .printfriendly {
373 display: none;
374 }
375 </style>
376 <?php
377 } catch (Exception $e) {
378 $this->raven_catch($e);
379 }
380 }
381
382 /**
383 * Prints the PrintFriendly JavaScript, in the footer, and loads it asynchronously.
384 *
385 * @since 3.0
386 */
387 function print_script_footer() {
388 if (isset($this->options['javascript']) && $this->options['javascript'] == 'no')
389 return;
390
391 else {
392 $tagline = $this->options['tagline'];
393 $image_url = $this->options['image_url'];
394 if( $this->options['logo'] == 'favicon' ) {
395 $tagline = '';
396 $image_url = '';
397 }
398
399 // Currently we use v3 for both: normal and password protected sites
400 ?>
401 <script type="text/javascript">
402
403 var pfHeaderImgUrl = '<?php echo esc_js(esc_url($image_url)); ?>';
404 var pfHeaderTagline = '<?php echo esc_js($tagline); ?>';
405 var pfdisableClickToDel = '<?php echo esc_js($this->options['click_to_delete']); ?>';
406 var pfImagesSize = '<?php echo esc_js($this->options['images-size']); ?>';
407 var pfImageDisplayStyle = '<?php echo esc_js($this->options['image-style']); ?>';
408 var pfDisableEmail = '<?php echo esc_js($this->options['email']); ?>';
409 var pfDisablePDF = '<?php echo esc_js($this->options['pdf']); ?>';
410 var pfDisablePrint = '<?php echo esc_js($this->options['print']); ?>';
411 var pfCustomCSS = '<?php echo esc_js(esc_url($this->options['custom_css_url'])); ?>';
412 (function() {
413 var e = document.createElement('script'); e.type="text/javascript";
414 e.src = 'https://cdn.printfriendly.com/printfriendly.js';
415 document.getElementsByTagName('head')[0].appendChild(e);
416 })();
417 </script>
418 <?php
419 }
420 }
421
422 /**
423 * Primary frontend function, used either as a filter for the_content, or directly using pf_show_link
424 *
425 * @since 3.0
426 * @param string $content the content of the post, when the function is used as a filter
427 * @return string $button or $content with the button added to the content when appropriate, just the content when button shouldn't be added or just button when called manually.
428 */
429 function show_link( $content = false ) {
430 try {
431 $is_manual = $this->is_manual();
432
433 if( !$content && !$is_manual )
434 return "";
435
436 $button = $this->getButton();
437 if ( $is_manual )
438 {
439 // Hook the script call now, so it only get's loaded when needed, and need is determined by the user calling pf_button
440 add_action( 'wp_footer', array( &$this, 'print_script_footer' ) );
441 return $button;
442 }
443
444 else
445 {
446 if ( (is_page() && ( isset($this->options['show_on_pages']) && 'on' === $this->options['show_on_pages'] ) )
447 || (is_home() && ( ( isset($this->options['show_on_homepage']) && 'on' === $this->options['show_on_homepage'] ) && $this->category_included() ) )
448 || (is_tax() && ( ( isset($this->options['show_on_taxonomies']) && 'on' === $this->options['show_on_taxonomies'] ) && $this->category_included() ) )
449 || (is_category() && ( ( isset($this->options['show_on_categories']) && 'on' === $this->options['show_on_categories'] ) && $this->category_included() ) )
450 || (is_single() && ( ( isset($this->options['show_on_posts']) && 'on' === $this->options['show_on_posts'] ) && $this->category_included() ) ) )
451 {
452 // Hook the script call now, so it only get's loaded when needed, and need is determined by the user calling pf_button
453 add_action( 'wp_footer', array( &$this, 'print_script_footer' ) );
454
455 if ( $this->options['content_placement'] == 'before' )
456 return $button.$content;
457 else
458 return $content.$button;
459 }
460 else
461 {
462 return $content;
463 }
464 }
465 } catch (Exception $e) {
466 $this->raven_catch($e);
467 }
468 }
469
470
471 /**
472 * @since 3.3.8
473 * @returns Printfriendly Button HTML
474 */
475
476 function getButton($add_footer_script = false) {
477 if($add_footer_script) {
478 add_action( 'wp_footer', array( &$this, 'print_script_footer' ) );
479 }
480 $js_enabled = $this->js_enabled();
481 $analytics_code = "";
482 $onclick = '';
483
484 if ( $this->google_analytics_enabled() ) {
485 $title_var = "NULL";
486 $analytics_code = "if(typeof(_gaq) != 'undefined') { _gaq.push(['_trackEvent','PRINTFRIENDLY', 'print', '".$title_var."']);
487 }else if(typeof(ga) != 'undefined') { ga('send', 'event','PRINTFRIENDLY', 'print', '".$title_var."'); }";
488 if( $js_enabled ) {
489 $onclick = 'onclick="window.print();'. $analytics_code .' return false;"';
490 } else {
491 $onclick = '';
492 }
493 } else if ( $js_enabled ) {
494 $onclick = 'onclick="window.print(); return false;"';
495 }
496
497 if( $js_enabled ){
498 $href = '#';
499 } else {
500 $href = 'https://www.printfriendly.com/print?url='.urlencode(get_permalink());
501 }
502
503 if (!$js_enabled) {
504 if($this->google_analytics_enabled()) {
505 $onclick = $onclick.' onclick="'.$analytics_code.'"';
506 }
507 $href = "https://www.printfriendly.com/print?headerImageUrl=".urlencode($this->options['image_url'])."&headerTagline=".urlencode($this->options['tagline'])."&pfCustomCSS=".urlencode($this->options['custom_css_url'])."&imageDisplayStyle=".urlencode($this->options['image-style'])."&disableClickToDel=".urlencode($this->options['click_to_delete'])."&disablePDF=".urlencode($this->options['pdf'])."&disablePrint=".urlencode($this->options['print'])."&disableEmail=".urlencode($this->options['email'])."&imagesSize=".urlencode($this->options['images-size'])."&url=".urlencode(get_permalink())."&source=wp";
508 }
509 if ( !is_singular() && '' != $onclick && $js_enabled) {
510 $onclick = '';
511 $href = add_query_arg('pfstyle','wp',get_permalink());
512 }
513
514 $align = '';
515 if ( 'none' != $this->options['content_position'] )
516 $align = ' pf-align'.$this->options['content_position'];
517 $href = str_replace("&", "&amp;", $href );
518 $button = apply_filters( 'printfriendly_button', '<div class="printfriendly'.$align.'"><a href="'.$href.'" rel="nofollow" '.$onclick.' class="noslimstat">'.$this->button().'</a></div>' );
519 return $button;
520 }
521
522
523 /**
524 * @since 3.2.9
525 * @returns if google analytics enabled
526 */
527 function google_analytics_enabled() {
528 return isset( $this->options['enable_google_analytics'] ) && $this->options['enable_google_analytics'] == 'yes';
529 }
530 /**
531 * @since 3.2.6
532 * @return boolean true if JS is enabled for the plugin
533 **/
534 function js_enabled() {
535 return isset( $this->options['javascript'] ) && $this->options['javascript'] == 'yes';
536 }
537
538 /**
539 * Filter posts by category.
540 *
541 * @since 3.2.2
542 * @return boolean true if post belongs to category selected for button display
543 */
544 function category_included() {
545 // return ( 'all' === $this->options['category_ids'][0] || in_category($this->options['category_ids']) );
546 return true;
547 }
548
549 /**
550 * Register the textdomain and the options array along with the validation function
551 *
552 * @since 3.0
553 */
554 function init() {
555 try {
556 // Allow for localization
557 load_plugin_textdomain( $this->hook, false, basename( dirname( __FILE__ ) ) . '/languages' );
558
559 // Register our option array
560 register_setting( $this->option_name, $this->option_name, array( &$this, 'options_validate' ) );
561 } catch (Exception $e) {
562 $this->raven_catch($e);
563 }
564 }
565
566 /**
567 * Validate the saved options.
568 *
569 * @since 3.0
570 * @param array $input with unvalidated options.
571 * @return array $valid_input with validated options.
572 */
573 function options_validate( $input ) {
574 // Prevent CSRF attack
575 check_admin_referer( 'pf-options', 'pf-nonce' );
576
577 $valid_input = $input;
578
579 // Section 1 options
580 if ( !isset( $input['button_type'] ) || !in_array( $input['button_type'], array(
581 'buttons/printfriendly-pdf-email-button.png',
582 'buttons/printfriendly-pdf-email-button-md.png',
583 'buttons/printfriendly-pdf-email-button-notext.png', // buttongroup1
584 'buttons/printfriendly-pdf-button.png',
585 'buttons/printfriendly-pdf-button-nobg.png',
586 'buttons/printfriendly-pdf-button-nobg-md.png', // buttongroup2
587 'buttons/printfriendly-button.png',
588 'buttons/printfriendly-button-nobg.png',
589 'buttons/printfriendly-button-md.png',
590 'buttons/printfriendly-button-lg.png', // buttongroup3
591 'buttons/print-button.png',
592 'buttons/print-button-nobg.png',
593 'buttons/print-button-gray.png', // buttongroup3
594 'custom-image' // custom
595 ) ) ) {
596 $valid_input['button_type'] = 'buttons/printfriendly-button.png';
597 }
598
599 // @todo custom image url validation
600 if ( !isset( $input['custom_image'] ) || empty( $input['custom_image'] ) )
601 $valid_input['custom_image'] = '';
602
603 // @todo validate optional custom text
604 if ( !isset( $input['custom_text'] ) ) {
605 $valid_input['custom_text'] = 'Print Friendly';
606 }
607 /* else {
608
609 }*/
610
611 // Custom button selected, but no url nor text given, reset button type to default
612 if( 'custom-image' === $valid_input['button_type'] && ( '' === $valid_input['custom_image'] && '' === $input['custom_text'] ) ) {
613 $valid_input['button_type'] = 'buttons/printfriendly-button.png';
614 add_settings_error( $this->option_name, 'invalid_custom_image', __( 'No valid custom image url received, please enter a valid url to use a custom image.', $this->hook ) );
615 }
616
617
618 $valid_input['text_size'] = (int) $input['text_size'];
619 if ( !isset($valid_input['text_size']) || 0 == $valid_input['text_size'] ) {
620 $valid_input['text_size'] = 14;
621 } else if ( 25 < $valid_input['text_size'] || 9 > $valid_input['text_size'] ) {
622 $valid_input['text_size'] = 14;
623 add_settings_error( $this->option_name, 'invalid_text_size', __( 'The text size you entered is invalid, please stay between 9px and 25px', $this->hook ) );
624 }
625
626 if ( !isset( $input['text_color'] )) {
627 $valid_input['text_color'] = $this->options['text_color'];
628 } else if ( ! preg_match('/^#[a-f0-9]{3,6}$/i', $input['text_color'] ) ) {
629 // Revert to previous setting and throw error.
630 $valid_input['text_color'] = $this->options['text_color'];
631 add_settings_error( $this->option_name, 'invalid_color', __( 'The color you entered is not valid, it must be a valid hexadecimal RGB font color.', $this->hook ) );
632 }
633
634
635
636 /* Section 2 options */
637 if ( !isset( $input['enable_css'] ) || 'off' !== $input['enable_css'] )
638 $valid_input['enable_css'] = 'on';
639
640 if ( !isset( $input['content_position'] ) || !in_array( $input['content_position'], array( 'none', 'left', 'center', 'right' ) ) )
641 $valid_input['content_position'] = 'left';
642
643 if ( !isset( $input['content_placement'] ) || !in_array( $input['content_placement'], array( 'before', 'after' ) ) )
644 $valid_input['content_placement'] = 'after';
645
646 foreach ( array( 'margin_top', 'margin_right', 'margin_bottom', 'margin_left' ) as $opt )
647 $valid_input[$opt] = (int) $input[$opt];
648
649 unset( $opt );
650
651
652 /* Section 3 options */
653 foreach ( array( 'show_on_posts', 'show_on_pages', 'show_on_homepage', 'show_on_categories', 'show_on_taxonomies' ) as $opt ) {
654 if ( !isset( $input[$opt] ) || 'on' !== $input[$opt] ) {
655 unset( $valid_input[$opt] );
656 }
657 }
658 unset( $opt );
659
660 // Just in case
661 if( isset( $input['show_on_template'] ) )
662 unset( $valid_input['show_on_template'] );
663
664
665 if( isset( $input['category_ids'] ) ) {
666 /**
667 * Validate received category ids:
668 * - Is there only one array item and does it contain the string text 'all' ? => pass
669 * - Otherwise, make sure the ids are integer values
670 */
671 /* $valid_input['category_ids'] = explode(',', $input['category_ids']);
672 $valid_input['category_ids'] = array_map( 'trim', $valid_input['category_ids'] );
673 if( ( count( $valid_input['category_ids'] ) === 1 && 'all' === $valid_input['category_ids'][0] ) === false ) {
674 foreach( $valid_input['category_ids'] as $k => $v ) {
675 if( $v !== '' && ( ctype_digit( (string) $v ) === true && ( intval( $v ) == $v ) ) ) {
676 $valid_input['category_ids'][$k] = intval( $v );
677 }
678 else {
679 // Invalid input - Show error message ?
680 unset( $valid_input['category_ids'][$k] );
681 }
682 }
683 }*/
684 unset( $valid_input['category_ids'] );
685 }
686
687 //echo '<pre>'.print_r($input,1).'</pre>';
688 //die;
689
690
691
692 /* Section 4 options */
693 if ( !isset( $input['logo'] ) || !in_array( $input['logo'], array( 'favicon', 'upload-an-image' ) ) )
694 $valid_input['logo'] = 'favicon';
695
696 // @todo custom logo url validation
697 if ( !isset( $input['image_url'] ) || empty( $input['image_url'] ) )
698 $valid_input['image_url'] = '';
699
700 // @todo validate optional tagline text
701 if ( !isset( $input['tagline'] ) ) {
702 $valid_input['tagline'] = '';
703 }
704 /* else {
705
706 }*/
707
708 // Custom logo selected, but no valid url given, reset logo to default
709 if( 'upload-an-image' === $valid_input['logo'] && '' === $valid_input['image_url'] ) {
710 $valid_input['logo'] = 'favicon';
711 add_settings_error( $this->option_name, 'invalid_custom_logo', __( 'No valid custom logo url received, please enter a valid url to use a custom logo.', $this->hook ) );
712 }
713
714
715 if ( !isset( $input['image-style'] ) || !in_array( $input['image-style'], array( 'right', 'left', 'none', 'block' ) ) )
716 $valid_input['image-style'] = 'right';
717
718
719 foreach( array( 'click_to_delete', 'email', 'pdf', 'print', ) as $opt ) {
720 if( !isset( $input[$opt] ) || !in_array( $input[$opt], array( '0', '1' ) ) ) {
721 $valid_input[$opt] = '0';
722 }
723 }
724 unset( $opt );
725
726 if( !isset( $input['images-size'] ) || !in_array( $input['images-size'], array( 'full-size', 'remove-images', 'large', 'medium', 'small' ) ) ) {
727 $valid_input['images-size'] = 'full-size';
728 }
729
730 // @todo custom css url validation
731 if ( !isset( $input['custom_css_url'] ) || empty( $input['custom_css_url'] ) )
732 $valid_input['custom_css_url'] = '';
733
734
735
736 /* Section 5 options */
737 if ( !isset( $input['password_protected'] ) || !in_array( $input['password_protected'], array( 'no', 'yes' ) ) )
738 $valid_input['password_protected'] = 'no';
739
740 if ( !isset( $input['javascript'] ) || !in_array( $input['javascript'], array( 'no', 'yes' ) ) )
741 $valid_input['javascript'] = 'yes';
742
743 /*Analytics Options */
744 if ( !isset( $input['enable_google_analytics'] ) || !in_array( $input['enable_google_analytics'], array( 'no', 'yes' ) ) ) {
745 $valid_input['enable_google_analytics'] = "no";
746 }
747
748 if ( !isset( $input['pf_algo'] ) || !in_array( $input['pf_algo'], array( 'wp', 'pf' ) ) ) {
749 $valid_input['pf_algo'] = "wp";
750 }
751
752 /* Database version */
753 $valid_input['db_version'] = $this->db_version;
754
755 return $valid_input;
756 }
757
758 /**
759 * Register the config page for all users that have the manage_options capability
760 *
761 * @since 3.0
762 */
763 function add_config_page() {
764 try {
765 $this->settings_page = add_options_page( __( 'PrintFriendly Options', $this->hook ), __( 'Print Friendly & PDF', $this->hook ), 'manage_options', $this->hook, array( &$this, 'config_page' ) );
766
767 //register callback gets call prior your own page gets rendered
768 add_action('load-'.$this->settings_page, array(&$this, 'on_load_printfriendly'));
769 } catch (Exception $e) {
770 $this->raven_catch($e);
771 }
772 }
773
774 /**
775 * Shows help on the plugin page when clicking on the Help button, top right.
776 *
777 * @since 3.0
778 */
779 function contextual_help( $contextual_help, $screen_id ) {
780 try {
781 if ( $this->settings_page == $screen_id ) {
782 $contextual_help = '<strong>'.__( "Need Help?", $this->hook ).'</strong><br/>'
783 .sprintf( __( "Be sure to check out the %s!", $this->hook), '<a href="https://wordpress.org/extend/plugins/printfriendly/faq/">'.__( "Frequently Asked Questions", $this->hook ).'</a>' );
784 }
785 return $contextual_help;
786 } catch (Exception $e) {
787 $this->raven_catch($e);
788 }
789 }
790
791 /**
792 * Enqueue the scripts for the admin settings page
793 *
794 * @since 3.0
795 * @param string $hook_suffix hook to check against whether the current page is the PrintFriendly settings page.
796 */
797 function admin_enqueue_scripts( $screen_id ) {
798 try {
799 if ( $this->settings_page == $screen_id ) {
800 $ver = '3.2.5';
801 wp_register_script( 'pf-color-picker', plugins_url( 'colorpicker.js', __FILE__ ), array( 'jquery', 'media-upload' ), $ver );
802 wp_register_script( 'pf-admin-js', plugins_url( 'admin.js', __FILE__ ), array( 'jquery', 'media-upload' ), $ver );
803
804 wp_enqueue_script( 'pf-color-picker' );
805 wp_enqueue_script( 'pf-admin-js' );
806
807
808 wp_enqueue_style( 'printfriendly-admin-css', plugins_url( 'admin.css', __FILE__ ), array(), $ver);
809 }
810 } catch (Exception $e) {
811 $this->raven_catch($e);
812 }
813 }
814
815 /**
816 * Register the settings link for the plugins page
817 *
818 * @since 3.0
819 * @param array $links the links for the plugins.
820 * @param string $file filename to check against plugins filename.
821 * @return array $links the links with the settings link added to it if appropriate.
822 */
823 function filter_plugin_actions( $links, $file ){
824 try {
825 // Static so we don't call plugin_basename on every plugin row.
826 static $this_plugin;
827 if ( ! $this_plugin ) $this_plugin = plugin_basename( __FILE__ );
828
829 if ( $file == $this_plugin ){
830 $settings_link = '<a href="options-general.php?page='.$this->hook.'">' . __( 'Settings', $this->hook ) . '</a>';
831 array_unshift( $links, $settings_link ); // before other links
832 }
833
834 return $links;
835 } catch (Exception $e) {
836 $this->raven_catch($e);
837 }
838 }
839
840 /**
841 * Set default values for the plugin. If old, as in pre 1.0, settings are there, use them and then delete them.
842 *
843 * @since 3.0
844 */
845 function set_defaults() {
846 try {
847 // Set some defaults
848 $this->options = array(
849 'button_type' => 'buttons/printfriendly-button.png',
850 'content_position' => 'left',
851 'content_placement' => 'after',
852 'custom_image' => 'https://cdn.printfriendly.com/icons/printfriendly-icon-md.png',
853 'custom_text' => 'Print Friendly',
854 'enable_css' => 'on',
855 'margin_top' => '12',
856 'margin_right' => '12',
857 'margin_bottom' => '12',
858 'margin_left' => '12',
859 'show_on_posts' => 'on',
860 'show_on_pages' => 'on',
861 'text_color' => '#6D9F00',
862 'text_size' => 14,
863 'logo' => 'favicon',
864 'image_url' => '',
865 'tagline' => '',
866 'click_to_delete' => '0', // 0 - allow, 1 - do not allow
867 'hide-images' => '0', // 0 - show images, 1 - hide images
868 'image-style' => 'right', // 'right', 'left', 'none', 'block'
869 'email' => '0', // 0 - allow, 1 - do not allow
870 'pdf' => '0', // 0 - allow, 1 - do not allow
871 'print' => '0', // 0 - allow, 1 - do not allow
872 'password_protected' => 'no',
873 'javascript' => 'yes',
874 'custom_css_url' => '',
875 'enable_google_analytics' => 'no',
876 'enable_error_reporting' => 'yes',
877 'pf_algo' => 'wp',
878 'images-size' => 'full-size'
879 );
880
881 // Check whether the old badly named singular options are there, if so, use the data and delete them.
882 foreach ( array_keys( $this->options ) as $opt ) {
883 $old_opt = get_option( 'pf_'.$opt );
884 if ( $old_opt !== false ) {
885 $this->options[$opt] = $old_opt;
886 delete_option( 'pf_'.$opt );
887 }
888 }
889
890 // This should always be set to the latest immediately when defaults are pushed in.
891 $this->options['db_version'] = $this->db_version;
892
893 update_option( $this->option_name, $this->options );
894 } catch (Exception $e) {
895 $this->raven_catch($e);
896 }
897 }
898
899 /**
900 * Upgrades the stored options, used to add new defaults if needed etc.
901 *
902 * @since 3.0
903 */
904 function upgrade() {
905 // update options to version 2
906 if($this->options['db_version'] < 2) {
907
908 $additional_options = array(
909 'enable_css' => 'on',
910 'logo' => 'favicon',
911 'image_url' => '',
912 'tagline' => '',
913 'click_to_delete' => '0',
914 'password_protected' => 'no',
915 'javascript' => 'yes'
916 );
917
918 // use old javascript_include value to initialize javascript
919 if(!isset($this->options['javascript_include']))
920 $additional_options['javascript'] = 'no';
921
922 unset($this->options['javascript_include']);
923 unset($this->options['javascript_fallback']);
924
925 // correcting badly named option
926 if(isset($this->options['disable_css'])) {
927 $additional_options['enable_css'] = $this->options['disable_css'];
928 unset($this->options['disable_css']);
929 }
930
931 // check whether image we do not list any more was used
932 if(in_array($this->options['button_type'], array('button-print-whgn20.png', 'pf_button_sq_qry_m.png', 'pf_button_sq_qry_l.png', 'pf_button_sq_grn_m.png', 'pf_button_sq_grn_l.png'))) {
933 // previous version had a bug with button name
934 if(in_array($this->options['button_type'], array('pf_button_sq_qry_m.png', 'pf_button_sq_qry_l.png')))
935 $this->options['button_type'] = str_replace('qry', 'gry', $this->options['button_type']);
936
937 $image_address = 'https://cdn.printfriendly.com/'.$this->options['button_type'];
938 $this->options['button_type'] = 'custom-image';
939 $this->options['custom_text'] = '';
940 $this->options['custom_image'] = $image_address;
941 }
942
943 $this->options = array_merge($this->options, $additional_options);
944 }
945
946 // update options to version 3
947 if($this->options['db_version'] < 3) {
948
949 $old_show_on = $this->options['show_list'];
950 // 'manual' setting
951 $additional_options = array('custom_css_url' => '');
952
953 if($old_show_on == 'all') {
954 $additional_options = array(
955 'show_on_pages' => 'on',
956 'show_on_posts' => 'on',
957 'show_on_homepage' => 'on',
958 'show_on_categories' => 'on',
959 'show_on_taxonomies' => 'on'
960 );
961 }
962
963 if($old_show_on == 'single') {
964 $additional_options = array(
965 'show_on_pages' => 'on',
966 'show_on_posts' => 'on'
967 );
968 }
969
970 if($old_show_on == 'posts') {
971 $additional_options = array(
972 'show_on_posts' => 'on',
973 );
974 }
975
976 unset($this->options['show_list']);
977
978 $this->options = array_merge($this->options, $additional_options);
979 }
980
981 // update options to version 4
982 if($this->options['db_version'] < 4) {
983
984 $additional_options = array(
985 'email' => '0',
986 'pdf' => '0',
987 'print' => '0',
988 );
989
990 $this->options = array_merge($this->options, $additional_options);
991 }
992
993 // update options to version 6
994 // Replacement for db version 5 - should also be run for those already upgraded
995 if($this->options['db_version'] < 6) {
996 unset($this->options['category_ids']);
997 }
998
999 if($this->options['db_version'] < 7) {
1000 $additional_options = array(
1001 'hide-images' => '0',
1002 'image-style' => 'right',
1003 );
1004
1005 $this->options = array_merge($this->options, $additional_options);
1006 }
1007
1008 if($this->options['db_version'] < 8) {
1009 $this->options['enable_google_analytics'] = 'no';
1010 }
1011
1012 if($this->options['db_version'] < 9) {
1013 $this->options['pf_algo'] = 'wp';
1014 }
1015
1016 if($this->options['db_version'] < 10) {
1017 $this->options['enable_error_reporting'] = 'yes';
1018 }
1019
1020 if($this->options['db_version'] < 11) {
1021 if (!isset($this->options['custom_css_url'])) {
1022 $this->options['custom_css_url'] = '';
1023 }
1024 }
1025
1026 if($this->options['db_version'] < 12) {
1027 $this->options['images-size'] = $this->options['hide-images'] == '1' ? 'remove-images' : 'full-size';
1028 }
1029
1030 if ($this->options['db_version'] < 13) {
1031 switch ($this->options['button_type']) {
1032 case 'pf-button.gif':
1033 $this->options['button_type'] = 'buttons/printfriendly-button.png';
1034 break;
1035 case 'pf-button-both.gif':
1036 $this->options['button_type'] = 'buttons/printfriendly-pdf-button.png';
1037 break;
1038 case 'pf-button-big.gif':
1039 $this->options['button_type'] = 'buttons/printfriendly-button-lg.png';
1040 break;
1041 case 'pf-button-print-pdf-mail.png':
1042 $this->options['button_type'] = 'buttons/printfriendly-pdf-email-button-notext.png';
1043 break;
1044 case 'button-print-grnw20.png':
1045 $this->options['button_type'] = 'buttons/print-button.png';
1046 break;
1047 case 'button-print-blu20.png':
1048 $this->options['button_type'] = 'buttons/print-button-nobg.png';
1049 break;
1050 case 'button-print-gry20.png':
1051 $this->options['button_type'] = 'buttons/print-button-gray.png';
1052 break;
1053 case 'pf-icon-small.gif':
1054 case 'pf-icon.gif':
1055 case 'text-only':
1056 $this->options['button_type'] = 'custom-image';
1057 $this->options['custom_image'] = 'icons/printfriendly-icon-md.png';
1058 break;
1059 default:
1060 $this->options['button_type'] = 'buttons/printfriendly-button.png';
1061 }
1062 }
1063
1064 $this->options['db_version'] = $this->db_version;
1065
1066 update_option( $this->option_name, $this->options );
1067 }
1068
1069 /**
1070 * Displays radio button in the admin area
1071 *
1072 * @since 3.0
1073 * @param string $name the name of the radio button to generate.
1074 * @param boolean $br whether or not to add an HTML <br> tag, defaults to true.
1075 */
1076 function radio($name, $br = false){
1077 $var = '<input id="'.$name.'" class="radio" name="'.$this->option_name.'[button_type]" type="radio" value="'.$name.'" '.$this->checked( 'button_type', $name, false ).'/>';
1078 $button = $this->button( $name );
1079 if ( '' != $button )
1080 echo '<label for="'.$name.'">' . $var . $button . '</label>';
1081 else
1082 echo $var;
1083
1084 if ( $br )
1085 echo '<br>';
1086 }
1087
1088 /**
1089 * Displays button image in the admin area
1090 *
1091 * @since 3.0
1092 * @param string $name the name of the button to generate.
1093 */
1094 function button( $name = false ){
1095 if( !$name )
1096 $name = $this->options['button_type'];
1097
1098 $button_css = $this->generic_button_css();
1099 /* esc_html was removerd to support custom html, CSRF prevents from attack by using this field */
1100 $text = $this->options['custom_text'];
1101 $img_path = 'https://cdn.printfriendly.com/';
1102
1103 if ($name == "custom-image") {
1104 if( '' == trim($this->options['custom_image']) )
1105 $return = '';
1106 else
1107 $return = '<img src="'.esc_url($this->options['custom_image']).'" alt="Print Friendly" style="display: inline" />';
1108
1109 $return .= $text;
1110
1111 return $return;
1112 } else {
1113 return '<img style="'.$button_css.'" src="'.$img_path.$name.'" alt="Print Friendly" />';
1114 }
1115 }
1116
1117 /**
1118 *
1119 *
1120 **/
1121
1122 function generic_button_css() {
1123 return "border:none;-webkit-box-shadow:none; box-shadow:none;";
1124 }
1125
1126
1127 /**
1128 * Convenience function to output a value custom button preview elements
1129 *
1130 * @since 3.0.9
1131 */
1132 function custom_button_preview() {
1133 if( '' == trim($this->options['custom_image']) )
1134 $button_preview = '<span id="pf-custom-button-preview"></span>';
1135 else
1136 $button_preview = '<span id="pf-custom-button-preview"><img src="'.esc_url($this->options['custom_image']).'" alt="Print Friendly" /></span>';
1137
1138 $button_preview .= '<span class="printfriendly-text2">'.esc_html($this->options['custom_text']).'</span>';
1139
1140 echo $button_preview;
1141 }
1142
1143 /**
1144 * Convenience function to output a value for an input
1145 *
1146 * @since 3.0
1147 * @param string $val value to check.
1148 */
1149 function val( $val ) {
1150 if ( isset( $this->options[$val] ) )
1151 echo esc_attr( $this->options[$val] );
1152 }
1153
1154 /**
1155 * Like the WordPress checked() function but it doesn't throw notices when the array key isn't set and uses the plugins options array.
1156 *
1157 * @since 3.0
1158 * @param mixed $val value to check.
1159 * @param mixed $check_against value to check against.
1160 * @param boolean $echo whether or not to echo the output.
1161 * @return string checked, when true, empty, when false.
1162 */
1163 function checked( $val, $check_against = true, $echo = true ) {
1164 if ( !isset( $this->options[$val] ) )
1165 return;
1166
1167 if ( $this->options[$val] == $check_against ) {
1168 if ( $echo )
1169 echo ' checked="checked" ';
1170 else
1171 return ' checked="checked" ';
1172 }
1173 }
1174
1175 /**
1176 * Helper for creating checkboxes.
1177 *
1178 * @since 3.1.5
1179 * @param string $name string used for various parts of checkbox
1180 *
1181 */
1182 function create_checkbox($name, $label='', $labelid='' ) {
1183 $label = ( !empty( $label) ? $label : __( ucfirst($name), $this->hook ) );
1184 echo '<label' . ( !empty( $labelid ) ? ' id=' . $labelid : '' ) . '><input type="checkbox" class="show_list" name="' . $this->option_name . '[show_on_' . $name . ']" value="on" ';
1185 $this->checked( 'show_on_' . $name, 'on');
1186 echo ' />' . $label . "</label>\r\n";
1187 }
1188
1189
1190 /**
1191 * Helper that checks if any of the content types is checked to display pf button.
1192 *
1193 * @since 3.1.5
1194 * @return boolean true if none of the content types is checked
1195 *
1196 */
1197 function is_manual() {
1198 try {
1199 return !(isset($this->options['show_on_posts']) ||
1200 isset($this->options['show_on_pages']) ||
1201 isset($this->options['show_on_homepage']) ||
1202 isset($this->options['show_on_categories']) ||
1203 // (isset($this->options['category_ids']) && count($this->options['category_ids']) > 0) ||
1204 isset($this->options['show_on_taxonomies']));
1205 } catch (Exception $e) {
1206 $this->raven_catch($e);
1207 }
1208 }
1209
1210
1211 /**
1212 * Like the WordPress selected() function but it doesn't throw notices when the array key isn't set and uses the plugins options array.
1213 *
1214 * @since 3.0.9
1215 * @param mixed $val value to check.
1216 * @param mixed $check_against value to check against.
1217 * @return string checked, when true, empty, when false.
1218 */
1219 function selected( $val, $check_against = true) {
1220 if ( !isset( $this->options[$val] ) )
1221 return;
1222
1223 return selected ($this->options[$val], $check_against);
1224 }
1225
1226 /**
1227 * For use with page metabox.
1228 *
1229 * @since 3.2.2
1230 */
1231 function get_page_post_type() {
1232 $post_types = get_post_types( array( 'name' => 'page' ), 'object' );
1233 //echo '<pre>'.print_r($post_types,1).'</pre>';
1234 //die;
1235
1236 return $post_types['page'];
1237 }
1238
1239
1240 /**
1241 * Helper that checks if wp versions is above 3.0.
1242 *
1243 * @since 3.2.2
1244 * @return boolean true wp version is above 3.0
1245 *
1246 */
1247 function wp_version_gt30() {
1248 global $wp_version;
1249 return version_compare($wp_version, '3.0', '>=');
1250 }
1251
1252
1253 /**
1254 * Create box for picking individual categories.
1255 *
1256 * @since 3.2.2
1257 */
1258 function create_category_metabox() {
1259 $obj = new stdClass();
1260 $obj->ID = 0;
1261 do_meta_boxes('settings_page_' . $this->hook, 'normal', $obj);
1262 }
1263
1264
1265 /**
1266 * Load metaboxes advanced button display settings.
1267 *
1268 * @since 3.2.2
1269 */
1270 function on_load_printfriendly() {
1271 global $wp_version;
1272 if($this->wp_version_gt30()) {
1273 require_once('includes/meta-boxes.php');
1274 //require_once('includes/nav-menu.php');
1275 wp_enqueue_script('post');
1276
1277 add_meta_box('categorydiv', __('Only display when post is in:', $this->hook), 'post_categories_meta_box', 'settings_page_'. $this->hook, 'normal', 'core');
1278 }
1279 }
1280
1281 function console_log( $data ) {
1282 echo '<script>';
1283 echo 'console.log(' . json_encode( $data ) . ')';
1284 echo '</script>';
1285 }
1286
1287 /**
1288 * Output the config page
1289 *
1290 * @since 3.0
1291 */
1292 function config_page() {
1293
1294
1295 // Since WP 3.2 outputs these errors by default, only display them when we're on versions older than 3.2 that do support the settings errors.
1296 global $wp_version;
1297 if(version_compare($wp_version, '3.2', '<' ) && $this->wp_version_gt30() )
1298 settings_errors();
1299
1300 // Show the content of the options array when debug is enabled
1301 if ( WP_DEBUG ) {
1302 echo "<p>" . __( 'Currently in Debug Mode. Following information is visible in debug mode only:', $this->hook ) . "</p>";
1303 echo '<pre>' . __( 'Options:', $this->hook ) . '<br><br>' . print_r( $this->options, 1 ) . '</pre>';
1304 }
1305 ?>
1306
1307 <style type="text/css">
1308 input[type="radio"], img {
1309 vertical-align: middle;
1310 }
1311 </style>
1312
1313 <div id="pf_settings" class="wrap">
1314
1315 <div class="icon32" id="printfriendly"></div>
1316 <h2><?php _e( 'Print Friendly & PDF Settings', $this->hook ); ?></h2>
1317
1318 <form action="options.php" method="post">
1319 <?php wp_nonce_field( 'pf-options', 'pf-nonce' ); ?>
1320 <?php settings_fields( $this->option_name ); ?>
1321
1322 <h3><?php _e( "Pick Your Button Style", $this->hook ); ?></h3>
1323
1324 <fieldset id="button-style">
1325 <div id="buttongroup1">
1326 <?php $this->radio('buttons/printfriendly-pdf-email-button.png'); ?>
1327 <?php $this->radio('buttons/printfriendly-pdf-email-button-md.png'); ?>
1328 <?php $this->radio('buttons/printfriendly-pdf-email-button-notext.png'); ?>
1329 </div>
1330 <div id="buttongroup2">
1331 <?php $this->radio('buttons/printfriendly-pdf-button.png'); ?>
1332 <?php $this->radio('buttons/printfriendly-pdf-button-nobg.png'); ?>
1333 <?php $this->radio('buttons/printfriendly-pdf-button-nobg-md.png'); ?>
1334 </div>
1335 <div id="buttongroup3">
1336 <?php $this->radio('buttons/printfriendly-button.png'); ?>
1337 <?php $this->radio('buttons/printfriendly-button-nobg.png'); ?>
1338 <?php $this->radio('buttons/printfriendly-button-md.png'); ?>
1339 <?php $this->radio('buttons/printfriendly-button-lg.png'); ?>
1340 </div>
1341 <div id="buttongroup4">
1342 <?php $this->radio('buttons/print-button.png'); ?>
1343 <?php $this->radio('buttons/print-button-nobg.png'); ?>
1344 <?php $this->radio('buttons/print-button-gray.png'); ?>
1345 </div>
1346
1347 <div id="custom" class="clear">
1348 <label for="custom-image">
1349 <?php echo '<input id="custom-image" class="radio" name="'.$this->option_name.'[button_type]" type="radio" value="custom-image" '.$this->checked( 'button_type', 'custom-image', false ).'/>'; ?>
1350 <?php _e( "Custom Button", $this->hook ); ?>
1351 </label>
1352
1353 <div id="custom-img">
1354 <div style="float: left">
1355 <span>PrintFriendly Icon Size</span>
1356 <select id="pf-icon" style="margin: 0">
1357 <option value="icons/printfriendly-icon-sm.png" <?php selected( $this->options['custom_image'], 'https://cdn.printfriendly.com/icons/printfriendly-icon-sm.png'); ?>>Small</option>
1358 <option value="icons/printfriendly-icon-md.png" <?php selected( $this->options['custom_image'], 'https://cdn.printfriendly.com/icons/printfriendly-icon-md.png'); ?>>Medium</option>
1359 <option value="icons/printfriendly-icon-lg.png" <?php selected( $this->options['custom_image'], 'https://cdn.printfriendly.com/icons/printfriendly-icon-lg.png'); ?>>Large</option>
1360 </select>
1361 </div>
1362
1363 <div style="float: left; margin-left: 50px">
1364 <?php _e( "Enter Image URL", $this->hook ); ?><br>
1365 <input id="custom_image" type="text" class="clear regular-text" style="width: 500px" name="<?php echo $this->option_name; ?>[custom_image]" value="<?php $this->val( 'custom_image' ); ?>" />
1366 <div class="description"><?php _e( "Ex: https://www.example.com/<br>Ex: /wp/wp-content/uploads/example.png", $this->hook ); ?>
1367 </div>
1368 </div>
1369 </div>
1370
1371 <div id="pf-custom-button-error"></div>
1372 <div id="custom-txt" >
1373 <div id="txt-enter">
1374 <?php _e( "Text", $this->hook ); ?><br>
1375 <input type="text" size="30" class="clear regular-text" name="<?php echo $this->option_name; ?>[custom_text]" id="custom_text" value="<?php $this->val( 'custom_text' ); ?>">
1376 </div>
1377 <div id="txt-color">
1378 <?php _e( "Text Color", $this->hook ); ?>
1379 <input type="hidden" name="<?php echo $this->option_name; ?>[text_color]" id="text_color" value="<?php $this->val( 'text_color' ); ?>"/><br>
1380 <div id="colorSelector">
1381 <div style="background-color: <?php echo $this->options['text_color']; ?>;"></div>
1382 </div>
1383 </div>
1384 <div id="txt-size">
1385 <?php _e( "Text Size", $this->hook ); ?><br>
1386 <input type="number" id="text_size" min="9" max="25" class="small-text" name="<?php echo $this->option_name; ?>[text_size]" value="<?php $this->val( 'text_size' ); ?>"/>
1387 </div>
1388 </div>
1389 <div id="custom-button-preview">
1390 <?php $this->custom_button_preview(); ?>
1391 </div>
1392 </fieldset>
1393 <br class="clear">
1394
1395 <!--Section 2 Button Positioning-->
1396 <div id="button-positioning">
1397 <h3><?php _e( "Button Positioning", $this->hook ); ?>
1398 <span id="css"><input type="checkbox" name="<?php echo $this->option_name; ?>[enable_css]" value="<?php $this->val('enable_css');?>" <?php $this->checked('enable_css', 'off'); ?> />Do not use CSS for button styles</span>
1399 </h3>
1400 <div id="button-positioning-options">
1401 <div id="alignment">
1402 <label<?php /*for="pf_content_position"*/ ?>>
1403 <select id="pf_content_position" name="<?php echo $this->option_name; ?>[content_position]" >
1404 <option value="left" <?php selected( $this->options['content_position'], 'left' ); ?>><?php _e( "Left Align", $this->hook ); ?></option>
1405 <option value="right" <?php selected( $this->options['content_position'], 'right' ); ?>><?php _e( "Right Align", $this->hook ); ?></option>
1406 <option value="center" <?php selected( $this->options['content_position'], 'center' ); ?>><?php _e( "Center", $this->hook ); ?></option>
1407 <option value="none" <?php selected( $this->options['content_position'], 'none' ); ?>><?php _e( "None", $this->hook ); ?></option>
1408 </select>
1409 </label>
1410 </div>
1411 <div class="content_placement">
1412 <label<?php /* for="pf_content_placement"*/ ?>>
1413 <select id="pf_content_placement" name="<?php echo $this->option_name; ?>[content_placement]" >
1414 <option value="before" <?php selected( $this->options['content_placement'], 'before' ); ?>><?php _e( "Above Content", $this->hook ); ?></option>
1415 <option value="after" <?php selected( $this->options['content_placement'], 'after' ); ?>><?php _e( "Below Content", $this->hook ); ?></option>
1416 </select>
1417 </label>
1418 </div>
1419 <div id="margin">
1420 <label for="pf-margin_left">
1421 <input type="number" name="<?php echo $this->option_name; ?>[margin_left]" id="pf-margin_left" value="<?php $this->val( 'margin_left' ); ?>" maxlength="3"/>
1422 <?php _e( "Margin Left", $this->hook ); ?>
1423 </label>
1424 <label for="pf-margin_right">
1425 <input type="number" name="<?php echo $this->option_name; ?>[margin_right]" id="pf-margin_right" value="<?php $this->val( 'margin_right' ); ?>"/> <?php _e( "Margin Right", $this->hook ); ?>
1426 </label>
1427 <label for="pf-margin_top">
1428 <input type="number" name="<?php echo $this->option_name; ?>[margin_top]" id="pf-margin_top" value="<?php $this->val( 'margin_top' ); ?>" maxlength="3"/> <?php _e( "Margin Top", $this->hook ); ?>
1429 </label>
1430 <label for="pf-margin_bottom">
1431 <input type="number" name="<?php echo $this->option_name; ?>[margin_bottom]" id="pf-margin_bottom" value="<?php $this->val( 'margin_bottom' ); ?>" maxlength="3"/> <?php _e( "Margin Bottom", $this->hook ); ?>
1432 </label>
1433 </div>
1434 </div>
1435 </div>
1436 <br class="clear">
1437
1438 <!--Section 3 Button Placement-->
1439 <div id="button-placement">
1440 <h3><?php _e( "Display button on:", $this->hook ); ?></h3>
1441 <div id="pages">
1442 <?php $this->create_checkbox('posts', __( 'Posts', $this->hook )); ?>
1443 <?php $this->create_checkbox('pages', __( 'Pages', $this->hook )); ?>
1444 <?php $this->create_checkbox('homepage', __( 'Homepage', $this->hook )); ?>
1445 <?php $this->create_checkbox('categories', __( 'Category Pages', $this->hook )); ?>
1446 <?php $this->create_checkbox('taxonomies', __( 'Taxonomy Pages', $this->hook )); ?>
1447 <label for="show_on_template"><input type="checkbox" class="show_template" name="show_on_template" id="show_on_template" /><?php echo _e( 'Add direct to template', $this->hook ); ?></label>
1448 <textarea id="pf-shortcode" class="code" rows="2" cols="40">&lt;?php if(function_exists('pf_show_link')){echo pf_show_link();} ?&gt;</textarea>
1449 <label<?php /* for="pf-shortcode2"*/ ?>><?php _e( "or use shortcode inside your page/article", $this->hook ); ?></label>
1450 <textarea<?php /* id="pf-shortcode2"*/ ?> class="code" rows="2" cols="40">[printfriendly]</textarea>
1451 <?php /* <input type="hidden" name="<? php echo $this->option_name; ?>[category_ids]" id="category_ids" value="<?php echo implode(',', $this->options['category_ids']); ? >" /> */ ?>
1452 </div>
1453 </div>
1454 <?php /*if($this->wp_version_gt30()) { ? >
1455 <div id="pf-categories">
1456 <h4><?php printf( __( '<a %s>Additional filter</a>', $this->hook), ' href="javascript:void(0)" id="toggle-categories"' ); ?></h4>
1457 <div id="pf-categories-metabox">
1458 <?php $this->create_category_metabox(); ?>
1459 </div>
1460 </div>
1461 <? php } */ ?>
1462
1463 <br class="clear">
1464
1465 <!--Section 4 Button Print Options-->
1466 <div id="print-options">
1467 <h3><?php _e( "Print PDF Options", $this->hook ); ?></h3>
1468 <label id="pf-favicon" for="favicon"<?php /*for="pf-logo"*/ ?>>
1469 <?php _e( "Page header", $this->hook ); ?>
1470 <select id="pf-logo" name="<?php echo $this->option_name; ?>[logo]" >
1471 <option value="favicon" <?php selected( $this->options['logo'], 'favicon' ); ?>><?php _e( "My Website Icon", $this->hook ); ?></option>
1472 <option value="upload-an-image" <?php selected( $this->options['logo'], 'upload-an-image' ); ?>><?php _e( "Upload an Image", $this->hook ); ?></option>
1473 </select>
1474 </label>
1475 <?php /* <div class="custom-logo">
1476 <label for="upload-an-image"><?php _e( "Enter url", $this->hook ); ?></label><input id="upload-an-image" type="text" class="regular-text" name="<?php echo $this->option_name; ?>[image_url]" value="<?php $this->val( 'image_url' ); ?>" />
1477 <label for="image-tagline"><?php _e( "Text (optional)", $this->hook ); ?></label><input id="image-tagline" type="text" class="regular-text" name="<?php echo $this->option_name; ?>[tagline]" value="<?php $this->val( 'tagline' ); ?>" />
1478 </div> */ ?>
1479 <div class="custom-logo"><label for="Enter_URL">Enter url</label><input id="upload-an-image" type="text" class="regular-text" name="<?php echo $this->option_name; ?>[image_url]" value="<?php $this->val( 'image_url' ); ?>" /><label for="Text__optional_">Text (optional)</label><input id="image-tagline" type="text" class="regular-text" name="<?php echo $this->option_name; ?>[tagline]" value="<?php $this->val( 'tagline' ); ?>" /></div>
1480 <div id="pf-image-error"></div>
1481 <div id="pf-image-preview"></div>
1482 <label for="click_to_delete">
1483 <?php _e( "Click-to-delete", $this->hook ); ?>
1484 <select name="<?php echo $this->option_name; ?>[click_to_delete]" id="click-to-delete">
1485 <option value="0" <?php selected( $this->options['click_to_delete'], '0' ); ?>><?php _e( "Allow", $this->hook ); ?></option>
1486 <option value="1" <?php selected( $this->options['click_to_delete'], '1' ); ?>><?php _e( "Not Allow", $this->hook ); ?></option>
1487 </select>
1488 </label>
1489 <label for="images-size">
1490 <?php _e( "Images", $this->hook ); ?>
1491 <select name="<?php echo $this->option_name; ?>[images-size]" id="images-size">
1492 <option value="full-size" <?php selected( $this->options['images-size'], 'full-size' ); ?>><?php _e( "Full Size", $this->hook ); ?></option>
1493 <option value="large" <?php selected( $this->options['images-size'], 'large' ); ?>><?php _e( "Large", $this->hook ); ?></option>
1494 <option value="medium" <?php selected( $this->options['images-size'], 'medium' ); ?>><?php _e( "Medium", $this->hook ); ?></option>
1495 <option value="small" <?php selected( $this->options['images-size'], 'small' ); ?>><?php _e( "Small", $this->hook ); ?></option>
1496 <option value="remove-images" <?php selected( $this->options['images-size'], 'remove-images' ); ?>><?php _e( "Remove Images", $this->hook ); ?></option>
1497 </select>
1498 </label>
1499 <label for="image-style">
1500 <?php _e( "Image style", $this->hook ); ?>
1501 <select name="<?php echo $this->option_name; ?>[image-style]" id="image-style">
1502 <option value="right" <?php selected( $this->options['image-style'], 'right' ); ?>><?php _e( "Align Right", $this->hook ); ?></option>
1503 <option value="left" <?php selected( $this->options['image-style'], 'left' ); ?>><?php _e( "Align Left", $this->hook ); ?></option>
1504 <option value="none" <?php selected( $this->options['image-style'], 'none' ); ?>><?php _e( "Align None", $this->hook ); ?></option>
1505 <option value="block" <?php selected( $this->options['image-style'], 'block' ); ?>><?php _e( "Center/Block", $this->hook ); ?></option>
1506 </select>
1507 </label>
1508 <label for="email">
1509 <?php _e( "Email", $this->hook ); ?>
1510 <select name="<?php echo $this->option_name; ?>[email]" id="email">
1511 <option value="0" <?php selected( $this->options['email'], '0' ); ?>><?php _e( "Allow", $this->hook ); ?></option>
1512 <option value="1" <?php selected( $this->options['email'], '1' ); ?>><?php _e( "Not Allow", $this->hook ); ?></option>
1513 </select>
1514 </label>
1515 <label for="pdf">
1516 <span class="alignleft"><?php _e( "PDF", $this->hook ); ?></span>
1517 <select name="<?php echo $this->option_name; ?>[pdf]" id="pdf" class="alignleft clear">
1518 <option value="0" <?php selected( $this->options['pdf'], '0' ); ?>><?php _e( "Allow", $this->hook ); ?></option>
1519 <option value="1" <?php selected( $this->options['pdf'], '1' ); ?>><?php _e( "Not Allow", $this->hook ); ?></option>
1520 </select>
1521 <p class="alignleft">
1522 <h4 class="alignleft notice"><abbr class="required"><?php _e( "Developer Note: ", $this->hook ); ?></abbr><?php _e( "On localhost the images can not be included in the PDF. Once the website is live/public images will be included in the PDF.", $this->hook ); ?></h4>
1523 </p>
1524 </label>
1525 <label for="print" class="clear">
1526 <?php _e( "Print", $this->hook ); ?>
1527 <select name="<?php echo $this->option_name; ?>[print]" id="print">
1528 <option value="0" <?php selected( $this->options['print'], '0' ); ?>><?php _e( "Allow", $this->hook ); ?></option>
1529 <option value="1" <?php selected( $this->options['print'], '1' ); ?>><?php _e( "Not Allow", $this->hook ); ?></option>
1530 </select>
1531 </label>
1532 <label for="custom_css_url">
1533 <?php _e( "Custom css url", $this->hook ); ?>
1534 <input id="custom_css_url" type="text" class="regular-text" name="<?php echo $this->option_name; ?>[custom_css_url]" value="<?php $this->val( 'custom_css_url' ); ?>" />
1535 <span class="description pf-help-link"><a target="_howto" href="https://support.printfriendly.com/customer/portal/articles/895256-custom-css-styles"><?php _e( '?', $this->hook ); ?></a></span>
1536 </label>
1537 </div>
1538
1539 <!--Section 5 WebMaster-->
1540 <h3><?php _e( "Webmaster Settings", $this->hook ); ?></h3>
1541
1542 <label for="password_protected"><?php _e( 'Password Protected Content', $this->hook ); ?>
1543 <select id="password_protected" name="<?php echo $this->option_name; ?>[password_protected]">
1544 <option value="no" <?php selected( $this->options['password_protected'], 'no' ); ?>><?php _e( "No", $this->hook ); ?></option>
1545 <option value="yes" <?php selected( $this->options['password_protected'], 'yes' ); ?>><?php _e( "Yes", $this->hook ); ?></option>
1546 </select>
1547 </label>
1548 <label for="javascript"><?php _e( 'Use JavaScript', $this->hook ); ?><br>
1549 <select id="javascript" name="<?php echo $this->option_name; ?>[javascript]>">
1550 <option value="yes" <?php $this->selected( 'javascript', 'yes' ); ?>> <?php _e( "Yes", $this->hook ); ?></option>
1551 <option value="no" <?php $this->selected( 'javascript', 'no' ); ?>> <?php _e( "No", $this->hook ); ?></option>
1552 </select>
1553 <span class="description javascript no-italics">
1554 <?php _e( "Preview appears on the page in a Lightbox.", $this->hook ); ?>
1555 </span>
1556 <span class="description no-javascript no-italics">
1557 <?php _e( "Preview opens a new browser tab.", $this->hook ); ?>
1558 </span>
1559 </label>
1560 <label for="pf-analytics-tracking"><?php _e( 'Track in Google Analytics', $this->hook ); ?><br>
1561 <select id="pf-analytics-tracking" name="<?php echo $this->option_name; ?>[enable_google_analytics]">
1562 <option value="yes" <?php $this->selected( 'enable_google_analytics', 'yes' ); ?>> <?php _e( "Yes", $this->hook ); ?></option>
1563 <option value="no" <?php $this->selected( 'enable_google_analytics', 'no' ); ?>> <?php _e( "No", $this->hook ); ?></option>
1564 </select>
1565 </label>
1566 <label for="pf-error-reporting"><?php _e( 'Error Reporting', $this->hook ); ?>
1567 <span class="description no-italics" ><?php _e( 'Ensure PrintFriendly is working - Automatically send anonymous alert if PrintFriendly encounters an error.', $this->hook ); ?>
1568 <br>
1569 <select id="pf-error-reporting" name="<?php echo $this->option_name; ?>[enable_error_reporting]">
1570 <option value="yes" <?php $this->selected( 'enable_error_reporting', 'yes' ); ?>> <?php _e( "Yes", $this->hook ); ?></option>
1571 <option value="no" <?php $this->selected( 'enable_error_reporting', 'no' ); ?>> <?php _e( "No", $this->hook ); ?></option>
1572 </select>
1573 </label>
1574 <label for="pf-algo-usage"><?php _e( 'My Page Content Selected By:', $this->hook ); ?> <span class="description no-italics" ><?php _e( 'Change this setting if your content is not showing in the preview.', $this->hook ); ?></span><br>
1575
1576 <?php
1577 if (class_exists('WooCommerce')) {
1578 ?>
1579 <span><strong>Not available for woocommerce</strong></span>
1580 <?php
1581 } else {
1582 ?>
1583 <select id="pf-algo-usage" name="<?php echo $this->option_name; ?>[pf_algo]">
1584 <option value="wp" <?php $this->selected( 'pf_algo', 'wp' ); ?>> <?php _e( 'WP Template', $this->hook ); ?></option>
1585 <option value="pf" <?php $this->selected( 'pf_algo', 'pf' ); ?>> <?php _e( "Content Algorithm", $this->hook ); ?></option>
1586 </select>
1587 <?php
1588 }
1589 ?>
1590
1591 </label>
1592
1593 <p class="submit">
1594 <input type="submit" class="button-primary" value="<?php esc_attr_e( "Save Options", $this->hook ); ?>"/>
1595 <input type="reset" class="button-secondary" value="<?php esc_attr_e( "Cancel", $this->hook ); ?>"/>
1596 </p>
1597 <div id="after-submit">
1598 <p>
1599 <?php _e( sprintf( __( 'If you like <strong>PrintFriendly</strong> please leave us a %s rating. A huge thanks in advance!', 'printfriendly' ), '<a href="https://wordpress.org/support/plugin/printfriendly/reviews?rate=5#new-post" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>' ), $this->hook ); ?>
1600 </p>
1601 <p><?php _e( "Need professional options for your corporate, education, or agency developed website? Check out", $this->hook ); ?> <a href="https://www.printfriendly.com/pro">PrintFriendly Pro</a>.</p>
1602 <p>
1603 <?php _e( "Need help or have suggestions?", $this->hook ); ?> <a href="mailto:support@printfriendly.com?subject=Support%20for%20PrintFriendly%20WordPress%20plugin">support@PrintFriendly.com</a>
1604 </p>
1605 </div>
1606 </form>
1607 <?php
1608 }
1609 }
1610 $printfriendly = new PrintFriendly_WordPress();
1611 }
1612
1613 // Add shortcode for printfriendly button
1614 add_shortcode( 'printfriendly', 'pf_show_link' );
1615
1616 /**
1617 * Convenience function for use in templates.
1618 *
1619 * @since 3.0
1620 * @return string returns a button to be printed.
1621 */
1622 function pf_show_link() {
1623 global $printfriendly;
1624 return $printfriendly->getButton(true);
1625 }
1626