Print, PDF, Email by PrintFriendly - Version 3.14.8

Version Description

  • Fix error from deprecated contextual help. Change printfriendly button CSS styles from internal (head) to inline (link). This ensures all styles are removed when button is not present.
Download this release

Release Info

Developer printfriendly
Plugin Icon 128x128 Print, PDF, Email by PrintFriendly
Version 3.14.8
Comparing to
See all releases

Code changes from version 3.14.7 to 3.14.8

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