PluginProbe
Embed PDF Viewer / 2.4.6
Embed PDF Viewer v2.4.6
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 2.4.6, at embed-pdf-viewer.php

291 lines 7.6 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.4.6
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( 'WPINC' ) ) {
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(
45 'init',
46 function () use ( $epd_version ) {
47 wp_set_script_translations( 'embed-pdf-viewer-scripts', 'embed-pdf-viewer' );
48
49 // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NoExplicitVersion
50 wp_enqueue_style(
51 'embed-pdf-viewer',
52 plugins_url( 'css/embed-pdf-viewer.css', __FILE__ ),
53 [],
54 $epd_version,
55 'screen'
56 );
57 }
58 );
59 add_action( 'init', [ Embed_PDF_Viewer::instance( $epd_version ), 'register_block' ] );
60
61 /**
62 * Class Embed_PDF_Viewer
63 */
64 class Embed_PDF_Viewer {
65 /**
66 * For singleton.
67 *
68 * @var bool
69 */
70 private static $instance = false;
71
72 /**
73 * Plugin version number.
74 *
75 * @var string
76 */
77 private static $version = '';
78
79 /**
80 * Create singleton.
81 *
82 * @param string $version Plugin version number.
83 * @return bool
84 */
85 public static function instance( $version ) {
86 static::$version = $version;
87 if ( false === static::$instance ) {
88 static::$instance = new self( $version );
89 }
90
91 return static::$instance;
92 }
93
94 /**
95 * Register block.
96 *
97 * @return void
98 */
99 public function register_block() {
100 if ( ! function_exists( 'register_block_type' ) ) {
101 return;
102 }
103
104 // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NoExplicitVersion
105 wp_register_script(
106 'embed-pdf-viewer',
107 plugins_url( 'blocks/build/index.js', __FILE__ ),
108 [ 'wp-i18n', 'wp-blocks', 'wp-block-editor', 'wp-element', 'wp-components', 'wp-compose', 'wp-blob' ],
109 static::$version,
110 true
111 );
112
113 register_block_type(
114 'embed-pdf-viewer/pdf',
115 [
116 'editor_script' => 'embed-pdf-viewer',
117 'render_callback' => [ static::$instance, 'dynamic_render_callback' ],
118 ]
119 );
120 }
121
122 /**
123 * Dynamically render callback based on browser.
124 *
125 * @global bool $is_chrome Tests for Chrome browser.
126 *
127 * @param array $attributes Array of attributes.
128 *
129 * @return string
130 */
131 public function dynamic_render_callback( $attributes ) {
132 global $is_chrome;
133
134 $url = $attributes['url'] ?? null;
135 if ( ! $url ) {
136 return '';
137 }
138
139 $classes = 'embed-pdf-viewer';
140 $src = $is_chrome || wp_is_mobile() ? 'https://docs.google.com/viewer?url=' . rawurlencode( $url ) . '&embedded=true' : $url;
141 $description = $attributes['title'] ?? '';
142 $description = $attributes['description'] ?? $description;
143 $width = $attributes['width'] ?? '600';
144 $height = $attributes['height'] ?? '600';
145 return sprintf(
146 '<iframe class="%1$s" src="%2$s" height="%3$s" width="%4$s" title="%5$s"%6$s></iframe>',
147 $classes,
148 sanitize_url( $src ),
149 esc_attr( $width ),
150 esc_attr( $height ),
151 esc_attr( $description ),
152 $is_chrome || wp_is_mobile() ? ' frameborder="0"' : ''
153 );
154 }
155
156 /**
157 * Insert URL to PDF from Media Library, then render as oEmbed.
158 *
159 * @param string $html an href link to the media.
160 * @param integer $id post_id.
161 *
162 * @return string
163 */
164 public function embed_pdf_media_editor( $html, $id ) {
165 $post = get_post( $id );
166 if ( 'application/pdf' !== $post->post_mime_type ) {
167 return $html;
168 }
169
170 return $post->guid . "\n\n";
171 }
172
173 /**
174 * Create oEmbed code.
175 *
176 * @param array $matches Regex matches.
177 * @param array $atts array of media height/width.
178 * @param string $url URI for media file.
179 *
180 * @return string|WP_Error
181 */
182 public function oembed_pdf_viewer( $matches, $atts, $url ) {
183 $attachment_id = $this->get_attachment_id_by_url( $url );
184 if ( ! empty( $attachment_id ) ) {
185 $post = get_post( $this->get_attachment_id_by_url( $url ) );
186 } else {
187 /*
188 * URL is from outside of the Media Library.
189 */
190 $response = wp_remote_get( $url );
191 if ( is_wp_error( $response ) ) {
192 return $response;
193 }
194 $post = new WP_Post( new stdClass() );
195 $post->guid = $matches[0];
196 $post->post_mime_type = wp_remote_retrieve_header( $response, 'content-type' );
197 $post->post_name = preg_replace( '/\.pdf$/', '', basename( $matches[0] ) );
198 }
199
200 return $this->create_output( $post, $atts );
201 }
202
203 /**
204 * Create output for iframe and/or Google Doc Viewer and href link to file.
205 *
206 * @param \WP_Post $post Current post.
207 * @param array|string $atts array of media height/width or
208 * href to media library asset.
209 *
210 * @return bool|string
211 */
212 private function create_output( WP_Post $post, $atts = [] ) {
213 global $is_chrome;
214
215 if ( 'application/pdf' !== $post->post_mime_type ) {
216 return $atts;
217 }
218
219 $default = [
220 'height' => 500,
221 'width' => 800,
222 'title' => $post->post_title,
223 'description' => $post->post_content,
224 ];
225
226 /*
227 * Ensure $atts isn't the href.
228 */
229 $atts = is_array( $atts ) ? $atts : [];
230
231 if ( isset( $atts['width'] ) ) {
232 $atts['width'] = '100%';
233 }
234 $atts = array_merge( $default, $atts );
235
236 /**
237 * Filter PDF attributes.
238 *
239 * @since 1.6.0
240 * @param array $atts Array of PDF attributes.
241 * @return array $atts
242 */
243 $atts = apply_filters( 'embed_pdf_viewer_pdf_attributes', $atts );
244
245 // Fix title or create from filename.
246 $atts['title'] = empty( $atts['title'] )
247 ? ucwords( preg_replace( '/(-|_)/', ' ', $post->post_name ) )
248 : ucwords( preg_replace( '/(-|_)/', ' ', $atts['title'] ) );
249
250 $description = ! empty( $atts['description'] ) ? $atts['description'] : $atts['title'];
251 $sanitized_url = sanitize_url( $post->guid );
252
253 if ( $is_chrome || wp_is_mobile() ) {
254 $iframe = '<iframe class="embed-pdf-viewer" src="https://docs.google.com/viewer?url=' . rawurlencode( $sanitized_url );
255 $iframe .= '&amp;embedded=true" frameborder="0" ';
256 } else {
257 $iframe = '<iframe class="embed-pdf-viewer" src="' . $sanitized_url . '" ';
258 }
259 $iframe .= 'height="' . esc_attr( $atts['height'] ) . '" width="' . esc_attr( $atts['width'] ) . '" ';
260 $iframe .= 'title="' . esc_attr( $description ) . '"></iframe>' . "\n";
261
262 $embed = '<div>';
263 $embed .= $iframe;
264 $embed .= '<p><a href="' . $sanitized_url . '" title="' . esc_attr( $description ) . '">' . esc_html( $description ) . '</a></p>';
265 $embed .= '</div>';
266
267 return $embed;
268 }
269
270 /**
271 * Get attachment id by url. Thanks Pippin.
272 *
273 * @link https://pippinsplugins.com/retrieve-attachment-id-from-image-url/
274 *
275 * @param string $url URI of attachment.
276 *
277 * @return mixed
278 */
279 private function get_attachment_id_by_url( $url ) {
280 global $wpdb;
281 // phpcs:ignore WordPress.DB
282 $attachment = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE guid='%s';", $url ) );
283
284 if ( empty( $attachment ) ) {
285 return null;
286 }
287
288 return $attachment[0];
289 }
290 }
291