PluginProbe
Embed PDF Viewer / trunk
Embed PDF Viewer vtrunk
trunk 0.1 1.0 1.0.1 1.1 1.1.1 1.1.2 1.2.0 1.2.1 1.3.0 1.4.0 1.5.0 1.6.0 1.6.1 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 2.1.2 2.2.0 2.3.0 All 35 releases
embed-pdf-viewer / embed-pdf-viewer.php

embed-pdf-viewer.php in Embed PDF Viewer trunk, at embed-pdf-viewer.php

261 lines 6.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Embed PDF Viewer
4 *
5 * @author Andy Fragen
6 * @license GPL-2.0+
7 * @link https://github.com/afragen/embed-pdf-viewer
8 * @package embed-pdf-viewer
9 */
10
11 /**
12 * Plugin Name: Embed PDF Viewer
13 * Plugin URI: https://github.com/afragen/embed-pdf-viewer
14 * Description: Embed a PDF from the Media Library or elsewhere via oEmbed or as a block into an `iframe` tag.
15 * Author: Andy Fragen
16 * Author URI: https://github.com/afragen
17 * Version: 2.5.1
18 * License: GPLv2+
19 * Domain Path: /languages
20 * Text Domain: embed-pdf-viewer
21 * License URI: http://www.gnu.org/licenses/gpl-2.0.html
22 * GitHub Plugin URI: https://github.com/afragen/embed-pdf-viewer
23 * Requires PHP: 7.4
24 * Requires at least: 6.0
25 */
26
27 /**
28 * Exit if called directly.
29 */
30 if ( ! defined( 'ABSPATH' ) ) {
31 die;
32 }
33
34 $epd_version = get_file_data( __FILE__, [ 'Version' => 'version' ] )['Version'];
35 add_filter( 'media_send_to_editor', [ Embed_PDF_Viewer::instance( $epd_version ), 'embed_pdf_media_editor' ], 20, 2 );
36 wp_embed_register_handler(
37 'oembed_pdf_viewer',
38 '#(^(https?)\:\/\/.+\.pdf$)#i',
39 [
40 Embed_PDF_Viewer::instance( $epd_version ),
41 'oembed_pdf_viewer',
42 ]
43 );
44 add_action( 'init', [ Embed_PDF_Viewer::instance( $epd_version ), 'register_block' ] );
45
46 /**
47 * Class Embed_PDF_Viewer
48 */
49 class Embed_PDF_Viewer {
50 /**
51 * For singleton.
52 *
53 * @var bool
54 */
55 private static $instance = false;
56
57 /**
58 * Plugin version number.
59 *
60 * @var string
61 */
62 private static $version = '';
63
64 /**
65 * Create singleton.
66 *
67 * @param string $version Plugin version number.
68 * @return bool
69 */
70 public static function instance( $version ) {
71 static::$version = $version;
72 if ( false === static::$instance ) {
73 static::$instance = new self( $version );
74 }
75
76 return static::$instance;
77 }
78
79 /**
80 * Register block.
81 *
82 * @return void
83 */
84 public function register_block() {
85 register_block_type(
86 __DIR__ . '/blocks/block.json',
87 [ 'render_callback' => [ static::$instance, 'dynamic_render_callback' ] ]
88 );
89 }
90
91 /**
92 * Dynamically render callback based on browser.
93 *
94 * @global bool $is_chrome Tests for Chrome browser.
95 *
96 * @param array $attributes Array of attributes.
97 *
98 * @return string
99 */
100 public function dynamic_render_callback( $attributes ) {
101 global $is_chrome;
102
103 $url = $attributes['url'] ?? null;
104 if ( ! $url ) {
105 return '';
106 }
107
108 $classes = 'embed-pdf-viewer';
109 $src = $is_chrome || wp_is_mobile() ? 'https://docs.google.com/viewer?url=' . rawurlencode( $url ) . '&embedded=true' : $url;
110 $description = $attributes['title'] ?? '';
111 $description = $attributes['description'] ?? $description;
112 $width = $attributes['width'] ?? '600';
113 $height = $attributes['height'] ?? '600';
114 $iframe = sprintf(
115 '<iframe class="%1$s" src="%2$s" height="%3$s" width="%4$s" title="%5$s"%6$s></iframe>',
116 $classes,
117 sanitize_url( $src ),
118 esc_attr( $height ),
119 esc_attr( $width ),
120 esc_attr( $description ),
121 $is_chrome || wp_is_mobile() ? ' frameborder="0"' : ''
122 );
123 $wrapper = get_block_wrapper_attributes( [ 'class' => 'embed-pdf-viewer-wrapper' ] );
124 return sprintf( '<div %1$s>%2$s</div>', $wrapper, $iframe );
125 }
126
127 /**
128 * Insert URL to PDF from Media Library, then render as oEmbed.
129 *
130 * @param string $html an href link to the media.
131 * @param integer $id post_id.
132 *
133 * @return string
134 */
135 public function embed_pdf_media_editor( $html, $id ) {
136 $post = get_post( $id );
137 if ( 'application/pdf' !== $post->post_mime_type ) {
138 return $html;
139 }
140
141 return $post->guid . "\n\n";
142 }
143
144 /**
145 * Create oEmbed code.
146 *
147 * @param array $matches Regex matches.
148 * @param array $atts array of media height/width.
149 * @param string $url URI for media file.
150 *
151 * @return string|WP_Error
152 */
153 public function oembed_pdf_viewer( $matches, $atts, $url ) {
154 $attachment_id = $this->get_attachment_id_by_url( $url );
155 if ( ! empty( $attachment_id ) ) {
156 $post = get_post( $attachment_id );
157 } else {
158 /*
159 * URL is from outside of the Media Library.
160 */
161 $response = wp_safe_remote_get( $url );
162 if ( is_wp_error( $response ) ) {
163 return $response;
164 }
165 $post = new WP_Post( new stdClass() );
166 $post->guid = $matches[0];
167 $post->post_mime_type = wp_remote_retrieve_header( $response, 'content-type' );
168 $post->post_name = preg_replace( '/\.pdf$/', '', basename( $matches[0] ) );
169 }
170
171 wp_enqueue_style(
172 'embed-pdf-viewer',
173 plugins_url( 'blocks/build/style-index.css', __FILE__ ),
174 [],
175 static::$version
176 );
177
178 return $this->create_output( $post, $atts );
179 }
180
181 /**
182 * Create output for iframe and/or Google Doc Viewer and href link to file.
183 *
184 * @param \WP_Post $post Current post.
185 * @param array|string $atts array of media height/width or
186 * href to media library asset.
187 *
188 * @return bool|string
189 */
190 private function create_output( WP_Post $post, $atts = [] ) {
191 global $is_chrome;
192
193 if ( 'application/pdf' !== $post->post_mime_type ) {
194 return $atts;
195 }
196
197 $default = [
198 'height' => 500,
199 'width' => 800,
200 'title' => $post->post_title,
201 'description' => $post->post_content,
202 ];
203
204 /*
205 * Ensure $atts isn't the href.
206 */
207 $atts = is_array( $atts ) ? $atts : [];
208
209 if ( isset( $atts['width'] ) ) {
210 $atts['width'] = '100%';
211 }
212 $atts = array_merge( $default, $atts );
213
214 /**
215 * Filter PDF attributes.
216 *
217 * @since 1.6.0
218 * @param array $atts Array of PDF attributes.
219 * @return array $atts
220 */
221 $atts = apply_filters( 'embed_pdf_viewer_pdf_attributes', $atts );
222
223 // Fix title or create from filename.
224 $atts['title'] = empty( $atts['title'] )
225 ? ucwords( preg_replace( '/(-|_)/', ' ', $post->post_name ) )
226 : ucwords( preg_replace( '/(-|_)/', ' ', $atts['title'] ) );
227
228 $description = ! empty( $atts['description'] ) ? $atts['description'] : $atts['title'];
229 $sanitized_url = sanitize_url( $post->guid );
230
231 if ( $is_chrome || wp_is_mobile() ) {
232 $iframe = '<iframe class="embed-pdf-viewer" src="https://docs.google.com/viewer?url=' . rawurlencode( $sanitized_url );
233 $iframe .= '&amp;embedded=true" frameborder="0" ';
234 } else {
235 $iframe = '<iframe class="embed-pdf-viewer" src="' . $sanitized_url . '" ';
236 }
237 $iframe .= 'height="' . esc_attr( $atts['height'] ) . '" width="' . esc_attr( $atts['width'] ) . '" ';
238 $iframe .= 'title="' . esc_attr( $description ) . '"></iframe>' . "\n";
239
240 $embed = '<div>';
241 $embed .= $iframe;
242 $embed .= '<p><a href="' . $sanitized_url . '" title="' . esc_attr( $description ) . '">' . esc_html( $description ) . '</a></p>';
243 $embed .= '</div>';
244
245 return $embed;
246 }
247
248 /**
249 * Get attachment id by url.
250 *
251 * @param string $url URI of attachment.
252 *
253 * @return int|null
254 */
255 private function get_attachment_id_by_url( $url ) {
256 $attachment = attachment_url_to_postid( $url );
257
258 return empty( $attachment ) ? null : $attachment;
259 }
260 }
261