PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / 2.21.13
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder v2.21.13
V-3.3.0 3.2.2 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 V3.0.3 V3.0.2 -3.0.1 V_3.0.0 1.1.1 1.1.8 1.2 1.3 1.4 1.4.18 1.5.2 1.9 2.0 2.10.0 2.10.1 2.10.2 All 137 releases
bit-form / includes / Core / Util / FileDownloadProvider.php

FileDownloadProvider.php in Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder 2.21.13, at includes/Core/Util/FileDownloadProvider.php

158 lines 5.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace BitCode\BitForm\Core\Util;
4
5 if (!defined('ABSPATH')) {
6 exit;
7 }
8
9 final class FileDownloadProvider
10 {
11 public function register()
12 {
13 add_action('template_redirect', [$this, 'authCheckandFrceDownloadHelper']);
14 add_shortcode('bitforms-frontend-file', [$this, 'handleFileDownload']);
15 }
16
17 public function handleFileDownload()
18 {
19 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- URL-based file download; nonce would break shareable download links.
20 if (!isset($_GET['formID']) || !isset($_GET['entryID']) || !isset($_GET['fileID'])) {
21 global $wp_query;
22 $wp_query->set_404();
23 status_header(404);
24 get_template_part(404);
25 exit();
26 }
27 $formID = intval(sanitize_text_field(wp_unslash($_GET['formID'])));
28 $entryID = intval(sanitize_text_field(wp_unslash($_GET['entryID'])));
29 $fileID = sanitize_file_name(wp_unslash($_GET['fileID']));
30 $filePath = FileHandler::getEntriesFileUploadDir($formID, $entryID) . DIRECTORY_SEPARATOR . $fileID;
31
32 if (is_readable($filePath)) {
33 $this->fileDownloadORView($filePath, true);
34 }
35 }
36
37 public static function getBaseDownloadURL()
38 {
39 $routes = get_option('bitforms_routes');
40 if (isset($routes['file'])) {
41 $file_page = get_post($routes['file']);
42 if (empty($file_page)) {
43 $file_route_id = wp_insert_post(
44 [
45 'post_name' => 'bitforms-file',
46 'comment_status' => 'closed',
47 'ping_status' => 'closed',
48 'post_content' => '<!-- wp:shortcode -->[bitforms-frontend-file /]<!-- /wp:shortcode -->',
49 'post_status' => 'publish',
50 'post_type' => 'bitforms'
51 ]
52 );
53 $routes['file'] = $file_route_id;
54 update_option('bitforms_routes', $routes);
55 $file_page_slug = get_post_permalink($file_route_id);
56 } else {
57 $file_page_slug = get_post_permalink($file_page->ID);
58 }
59 } else {
60 $file_route_id = wp_insert_post(
61 [
62 'post_name' => 'bitforms-file',
63 'comment_status' => 'closed',
64 'ping_status' => 'closed',
65 'post_content' => '<!-- wp:shortcode -->[bitforms-frontend-file /]<!-- /wp:shortcode -->',
66 'post_status' => 'publish',
67 'post_type' => 'bitforms'
68 ]
69 );
70 $route_value = [];
71 $route_value['file'] = $file_route_id;
72 update_option('bitforms_routes', $route_value);
73 $file_page_slug = get_post_permalink($file_route_id);
74 }
75
76 return $file_page_slug;
77 }
78
79 public function authCheckandFrceDownloadHelper()
80 {
81 if (!is_singular('bitforms')) {
82 return;
83 }
84 global $post;
85 if (!empty($post->post_content)) {
86 $shortCodeRegex = get_shortcode_regex();
87 preg_match_all('/' . $shortCodeRegex . '/', $post->post_content, $regexMatchGroups);
88 if (!empty($regexMatchGroups[2]) && in_array('bitforms-frontend-file', $regexMatchGroups[2]) && is_user_logged_in()) {
89 $file = $this->isRequestedFileExists();
90 if ($file) {
91 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- URL-based file access; auth handled via is_user_logged_in() check above.
92 $this->fileDownloadORView($file, isset($_GET['download']));
93 } else {
94 $this->show404();
95 }
96 } else {
97 auth_redirect();
98 }
99 }
100 }
101
102 private function show404()
103 {
104 global $wp_query;
105 $wp_query->set_404();
106 status_header(404);
107 get_template_part(404);
108 exit();
109 }
110
111 private function isRequestedFileExists()
112 {
113 if (!isset($_GET['formID']) || !isset($_GET['entryID']) || !isset($_GET['fileID'])) {
114 return false;
115 }
116 $formID = intval(sanitize_text_field(wp_unslash($_GET['formID'])));
117 $entryID = intval(sanitize_text_field(wp_unslash($_GET['entryID'])));
118 $fileID = sanitize_file_name(wp_unslash($_GET['fileID']));
119 $filePath = FileHandler::getEntriesFileUploadDir($formID, $entryID) . DIRECTORY_SEPARATOR . $fileID;
120 if (is_readable($filePath)) {
121 return $filePath;
122 }
123
124 return false;
125 }
126
127 private function fileDownloadORView($filePath, $forceDownload = false)
128 {
129 if ($forceDownload) {
130 header('Content-Type: application/force-download');
131 header('Content-Type: application/octet-stream');
132 header('Content-Type: application/download');
133 header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
134 } else {
135 $fileInfo = wp_check_filetype($filePath);
136 $content_types = 'text/plain';
137 if ($fileInfo['type'] && $fileInfo['ext']) {
138 $content_types = $fileInfo['type'];
139 $ext = $fileInfo['ext'];
140 if (in_array($ext[1], ['txt', 'php', 'html', 'xhtml', 'json'])) {
141 $content_types = 'text/plain';
142 }
143 }
144 header('Content-Disposition:filename="' . basename($filePath) . '"');
145 header("Content-Type: $content_types");
146 }
147 header('Content-Description: File Transfer');
148 header('Expires: 0');
149 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
150 header('Pragma: public');
151 header('Content-Length: ' . filesize($filePath));
152 header('Content-Transfer-Encoding: binary ');
153 flush();
154 readfile($filePath); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_readfile
155 die();
156 }
157 }
158