PluginProbe
Document Embedder – let visitors read files without downloading / trunk
Document Embedder – let visitors read files without downloading vtrunk
2.3.1 2.3.0 2.2.1 2.2.0 2.1.2 2.1.1 trunk 1.0 1.1 1.2 1.3 1.7.4 1.7.6 1.7.9 1.8.1 1.8.2 1.8.3 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 2.0.0 2.0.1 2.0.2 All 30 releases
document-emberdder / includes / features / class-bplde-shortcode.php

class-bplde-shortcode.php in Document Embedder – let visitors read files without downloading trunk, at includes/features/class-bplde-shortcode.php

315 lines 14.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * BPLDE Shortcode Controller.
4 *
5 * @package DocumentEmbedder
6 */
7
8 namespace BPLDE\Model;
9
10 use BPLDE\Helper\Functions;
11 use BPLDE\Helper\DefaultArgs;
12
13 if (!defined('ABSPATH')) {
14 exit;
15 }
16
17 if (!class_exists('Shortcode')) {
18 class Shortcode {
19 protected static $_instance = null;
20
21 public function __construct()
22 {
23 add_shortcode('doc', [$this, 'doc']);
24 }
25
26 public static function instance()
27 {
28 if (self::$_instance === null) {
29 self::$_instance = new self();
30 }
31 return self::$_instance;
32 }
33
34 public function doc($atts)
35 {
36 $post_type = get_post_type($atts['id']);
37
38 if ($post_type != 'ppt_viewer') {
39 return false;
40 }
41
42 $post_id = $atts['id'];
43 $post = get_post($post_id);
44 if (post_password_required($post)) {
45 return get_the_password_form($post);
46 }
47
48 switch ($post->post_status) {
49 case 'publish':
50 return $this->html($atts['id'], $atts);
51
52 case 'private':
53 if (current_user_can('read_private_posts')) {
54 return $this->html($atts['id'], $atts);
55 }
56 return '';
57
58 case 'draft':
59 case 'pending':
60 case 'future':
61 if (current_user_can('edit_post', $post_id)) {
62 return $this->html($atts['id'], $atts);
63 }
64 return '';
65
66 default:
67 return '';
68 }
69 }
70
71 public function doc_data($id, $atts = [])
72 {
73 $width = Functions::meta($id, 'width', ['width' => '100', 'unit' => '%']);
74 $height = Functions::meta($id, 'height', ['height' => 600, 'unit' => 'px']);
75
76 $result = [
77 'doc' => Functions::meta($id, 'doc', ''),
78 'width' => $width['width'] . $width['unit'],
79 'height' => $height['height'] . $height['unit'],
80 'width_tablet' => Functions::meta($id, 'width_tablet', ''),
81 'width_mobile' => Functions::meta($id, 'width_mobile', ''),
82 'height_tablet' => Functions::meta($id, 'height_tablet', ''),
83 'height_mobile' => Functions::meta($id, 'height_mobile', ''),
84 'showName' => Functions::meta($id, 'showName'),
85 'download' => Functions::meta($id, 'download', '0'),
86 'downloadButtonText' => Functions::meta($id, 'downloadButtonText', Functions::meta($id, '_de_download_label', 'Download')),
87 '_de_download_position' => Functions::meta($id, '_de_download_position', 'toolbar'),
88 '_de_toolbar_theme' => Functions::meta($id, '_de_toolbar_theme', 'dark'),
89 '_de_toolbar_bg_color' => Functions::meta($id, '_de_toolbar_bg_color', '#343434'),
90 '_de_toolbar_text_color' => Functions::meta($id, '_de_toolbar_text_color', '#ffffff'),
91 '_de_download_behavior' => Functions::meta($id, '_de_download_behavior', 'download'),
92 '_de_download_filename' => Functions::meta($id, '_de_download_filename', ''),
93 '_de_download_show_count' => Functions::meta($id, '_de_download_show_count', '0'),
94 '_de_download_limit' => Functions::meta($id, '_de_download_limit', '0'),
95 'viewer' => Functions::meta($id, 'viewer', 'default'),
96 'enableFullscreen' => Functions::meta($id, 'enableFullscreen', false),
97 'onDemandRendering' => Functions::meta($id, 'onDemandRendering', false),
98 'fullscreenNewTab' => Functions::meta($id, 'fullscreenNewTab', false),
99 'readerMode' => Functions::meta($id, 'readerMode', false),
100 'toggleThumbnails' => Functions::meta($id, 'toggleThumbnails', false),
101 'sidebarOpen' => Functions::meta($id, 'sidebarOpen', false),
102 'loadLatestVersion' => Functions::meta($id, 'loadLatestVersion', false),
103 'hrScrollbar' => Functions::meta($id, 'hrScrollbar', false),
104 'initialPage' => Functions::meta($id, 'initialPage', 1),
105 'defaultZoom' => Functions::meta($id, 'defaultZoom', ''),
106 'gviewFallback' => Functions::meta($id, 'gviewFallback', true),
107 'lazyLoad' => Functions::meta($id, 'lazyLoad', false),
108 'lightbox_trigger_type' => Functions::meta($id, 'lightbox_trigger_type', 'button'),
109 'lightbox_trigger_selector' => Functions::meta($id, 'lightbox_trigger_selector', ''),
110 'lightbox_trigger_image' => self::extract_media_url(Functions::meta($id, 'lightbox_trigger_image', '')),
111 'lightbox_trigger_image_width' => Functions::meta($id, 'lightbox_trigger_image_width', '300px'),
112 'lightbox_trigger_image_height' => Functions::meta($id, 'lightbox_trigger_image_height', 'auto'),
113 'lightbox_trigger_image_radius' => Functions::meta($id, 'lightbox_trigger_image_radius', '8px'),
114 'lightbox_trigger_image_align' => Functions::meta($id, 'lightbox_trigger_image_align', 'left'),
115 'lightbox_trigger_image_fit' => Functions::meta($id, 'lightbox_trigger_image_fit', 'cover'),
116 'id' => $id
117 ];
118
119 if (empty($result['_de_download_label'])) {
120 $result['_de_download_label'] = $result['downloadButtonText'] ? $result['downloadButtonText'] : 'Download';
121 }
122
123 $override_map = [
124 'download' => 'download',
125 'download_label' => '_de_download_label',
126 'download_position' => '_de_download_position',
127 'download_behavior' => '_de_download_behavior',
128 'download_filename' => '_de_download_filename',
129 'download_limit' => '_de_download_limit',
130 'show_count' => '_de_download_show_count',
131 'toolbar_theme' => '_de_toolbar_theme',
132 'toolbar_bg_color' => '_de_toolbar_bg_color',
133 'toolbar_text_color' => '_de_toolbar_text_color',
134 ];
135 foreach ($override_map as $att_key => $data_key) {
136 if (isset($atts[$att_key])) {
137 if (in_array($atts[$att_key], ['yes', 'true', '1'], true)) {
138 $result[$data_key] = '1';
139 } elseif (in_array($atts[$att_key], ['no', 'false', '0'], true)) {
140 $result[$data_key] = '0';
141 } else {
142 $result[$data_key] = $atts[$att_key];
143 }
144 }
145 }
146
147 // Check Limit per IP
148 $limit = (int) $result['_de_download_limit'];
149 $result['limit_reached'] = false;
150 if ($limit > 0) {
151 global $wpdb;
152 $ip = Functions::get_client_ip();
153 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- querying custom table
154 $downloaded_count = $wpdb->get_var($wpdb->prepare(
155 "SELECT COUNT(*) FROM {$wpdb->prefix}docembedder_leads WHERE document_id = %d AND ip_address = %s",
156 $id,
157 $ip
158 ));
159
160 if ((int) $downloaded_count >= $limit) {
161 $result['limit_reached'] = true;
162 }
163 }
164
165 $result = apply_filters('bplde_doc_data', $result, $id);
166 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- backward compatibility hook
167 return apply_filters('ppv_doc_data', $result, $id);
168 }
169
170 /**
171 * Normalize a media field value to a plain URL string.
172 * CSF 'media' fields may store an array (url/id/…); the block editor stores a URL string.
173 */
174 public static function extract_media_url($value)
175 {
176 if (is_array($value)) {
177 return isset($value['url']) ? $value['url'] : '';
178 }
179 return $value ? $value : '';
180 }
181
182 public static function get_block_attributes($data)
183 {
184 $parse_dim = function ($prop, $default, $type = 'width') {
185 if (is_array($prop)) {
186 if (isset($prop[$type]) && $prop[$type] !== '') {
187 return $prop[$type] . (isset($prop['unit']) ? $prop['unit'] : 'px');
188 }
189 return $default;
190 }
191 $val = !empty($prop) ? $prop : $default;
192 return is_numeric($val) ? $val . 'px' : $val;
193 };
194
195 $w_d = $parse_dim(isset($data['width']) ? $data['width'] : '', '100%', 'width');
196 $w_t = $parse_dim(isset($data['width_tablet']) ? $data['width_tablet'] : '', $w_d, 'width');
197 $w_m = $parse_dim(isset($data['width_mobile']) ? $data['width_mobile'] : '', $w_t, 'width');
198
199 $h_d = $parse_dim(isset($data['height']) ? $data['height'] : '', '600px', 'height');
200 $h_t = $parse_dim(isset($data['height_tablet']) ? $data['height_tablet'] : '', $h_d, 'height');
201 $h_m = $parse_dim(isset($data['height_mobile']) ? $data['height_mobile'] : '', $h_t, 'height');
202
203 $viewer = isset($data['viewer']) ? $data['viewer'] : 'default';
204 // Full-Screen and On-Demand Rendering are Custom-PDF-viewer-only features.
205 // Gate them server-side so they can never alter the Default (Google Drive) viewer path,
206 // even if the raw meta value is somehow truthy on a non-custom viewer.
207 $is_custom_viewer = ($viewer === 'custom');
208 $is_custom_or_flipbook_or_slider = in_array($viewer, ['custom', 'flipbook', 'slider'], true);
209 $truthy = ['1', 1, 'true', true, 'yes'];
210
211 return [
212 'docId' => isset($data['id']) ? intval($data['id']) : 0,
213 'documentSource' => [
214 'doc' => isset($data['doc']) ? $data['doc'] : '',
215 'viewer' => $viewer,
216 'googleDrive' => isset($data['googleDrive']) && in_array($data['googleDrive'], ['1', 1, 'true', true, 'yes'], true),
217 'enableFullscreen' => false,
218 'onDemandRendering' => false,
219 'fullscreenNewTab' => false,
220 'readerMode' => false,
221 'toggleThumbnails' => false,
222 'sidebarOpen' => false,
223 'loadLatestVersion' => false,
224 'hrScrollbar' => false,
225 'initialPage' => 1,
226 'defaultZoom' => '',
227 ],
228 'toolbar' => [
229 'showName' => isset($data['showName']) && in_array($data['showName'], ['1', 1, 'true', true, 'yes'], true),
230 'download' => isset($data['download']) && in_array($data['download'], ['1', 1, 'true', true, 'yes'], true),
231 '_de_download_position' => isset($data['_de_download_position']) ? $data['_de_download_position'] : 'toolbar',
232 'theme' => 'dark',
233 'toolbar_bg_color' => '#343434',
234 'toolbar_text_color' => '#ffffff',
235 ],
236 'displayDimensions' => [
237 'width' => [
238 'desktop' => $w_d,
239 'tablet' => $w_t,
240 'mobile' => $w_m,
241 ],
242 'height' => [
243 'desktop' => $h_d,
244 'tablet' => $h_t,
245 'mobile' => $h_m,
246 ]
247 ],
248 'securityRestrictions' => [
249 'disablePopout' => false,
250 'loading_icon' => false,
251 ],
252 'downloadManagement' => [
253 'downloadButtonText' => isset($data['downloadButtonText']) ? $data['downloadButtonText'] : 'Download',
254 '_de_download_behavior' => isset($data['_de_download_behavior']) ? $data['_de_download_behavior'] : 'download',
255 '_de_download_filename' => isset($data['_de_download_filename']) ? $data['_de_download_filename'] : '',
256 '_de_download_show_count' => isset($data['_de_download_show_count']) && in_array($data['_de_download_show_count'], ['1', 1, 'true', true, 'yes'], true),
257 '_de_download_limit' => isset($data['_de_download_limit']) ? intval($data['_de_download_limit']) : 0,
258 '_de_download_access' => 'everyone',
259 '_de_download_access_roles' => [],
260 '_de_download_access_message' => 'Access Denied',
261 '_de_email_gate' => false,
262 ],
263 'lightbox' => [
264 'lightbox' => false,
265 'lightbox_btn_text' => 'View Document',
266 'lightbox_btn_color' => '#ffffff',
267 'lightbox_btn_background' => '#333333',
268 'lightbox_btn_size' => 'medium',
269 'lightbox_trigger_type' => 'button',
270 'lightbox_trigger_selector' => '',
271 'lightbox_trigger_image' => '',
272 'lightbox_trigger_image_width' => '300px',
273 'lightbox_trigger_image_height' => 'auto',
274 'lightbox_trigger_image_radius' => '8px',
275 'lightbox_trigger_image_align' => 'left',
276 'lightbox_trigger_image_fit' => 'cover',
277 ],
278 'performance' => [
279 'lazyLoad' => false,
280 'gviewFallback' => true,
281 ]
282 ];
283 }
284
285 public function html($id, $atts = [])
286 {
287 $data = $this->doc_data($id, $atts);
288 $data = DefaultArgs::parseArgs($data);
289
290 $block = [
291 'blockName' => 'bplde/document-embed',
292 'attrs' => self::get_block_attributes($data),
293 'innerHTML' => '',
294 'innerContent' => [],
295 ];
296
297 wp_enqueue_script('bplde-document-embed-view-script');
298 wp_enqueue_style('bplde-document-embed-style');
299
300 $viewer = isset($data['viewer']) ? $data['viewer'] : 'default';
301 if (in_array($viewer, ['flipbook', 'slider'], true) && wp_script_is('bplde-dflip-script', 'registered')) {
302 wp_enqueue_script('bplde-dflip-script');
303 wp_enqueue_style('bplde-dflip-style');
304 }
305
306 $output = render_block($block);
307 $output = apply_filters('bplde_shortcode_html', $output, $data);
308 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- backward compatibility hook
309 return apply_filters('ppv_shortcode_html', $output, $data);
310 }
311 }
312
313 Shortcode::instance();
314 }
315