PluginProbe
Hash Form – Drag & Drop Form Builder / trunk
Hash Form – Drag & Drop Form Builder vtrunk
1.4.4 1.4.3 1.4.2 1.4.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.6.1 1.2.7 1.2.8 1.2.9 1.3.0 All 47 releases
hash-form / includes / fields / HashFormFieldUpload.php

HashFormFieldUpload.php in Hash Form – Drag & Drop Form Builder trunk, at includes/fields/HashFormFieldUpload.php

209 lines 10.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 defined('ABSPATH') || die();
3
4 class HashFormFieldUpload extends HashFormFieldType {
5
6 protected $type = 'upload';
7
8 protected function field_settings_for_type() {
9 return array(
10 'default' => false,
11 );
12 }
13
14 protected function extra_field_default_opts() {
15 return array(
16 'upload_label' => esc_html__('Upload File', 'hash-form'),
17 'max_upload_size' => 10,
18 'min_upload_size' => '',
19 'extensions' => 'jpg,jpeg,gif,png',
20 'extensions_error_message' => esc_html__('Invalid Extension', 'hash-form'),
21 'multiple_uploads' => 'on',
22 'multiple_uploads_limit' => 5,
23 'multiple_uploads_error_message' => esc_html__('Maximum file upload limit exceeded', 'hash-form'),
24 );
25 }
26
27 protected function input_html() {
28 $field = $this->get_field();
29 $max_size = isset($field['max_upload_size']) ? absint($field['max_upload_size']) : '';
30 $max_size = $max_size ? $max_size : 10;
31 $max_size = $max_size * 1024 * 1024;
32 // Kilobytes in the builder, because the useful values here are small,
33 // but bytes on the wire to match the maximum.
34 $min_size = isset($field['min_upload_size']) ? absint($field['min_upload_size']) : 0;
35 $min_size = $min_size * 1024;
36 $new_extensions = isset($field['extensions']) ? hashform_sanitize_allowed_file_extensions($field['extensions']) : 'jpg,jpeg,gif,png';
37
38 if (is_admin() && !HashFormHelper::is_preview_page()) {
39 // Static twin of the dropzone frontend.js builds, so the builder
40 // shows what the visitor will see. The uploader script never runs
41 // on this screen, so there is no list and no drop overlay, and the
42 // id has to stay on the button itself because the label setting
43 // live updates it by id.
44 ?>
45 <div class="hf-file-uploader-wrapper">
46 <div class="hf-file-uploader">
47 <div class="qq-uploader">
48 <div class="hf-upload-dropzone">
49 <?php self::dropzone_icon(); ?>
50 <span class="hf-upload-dropzone-title">
51 <?php
52 echo isset($field['multiple_uploads']) && $field['multiple_uploads'] == 'on'
53 ? esc_html__('Drag and drop your files here', 'hash-form')
54 : esc_html__('Drag and drop your file here', 'hash-form');
55 ?>
56 </span>
57 <span class="hf-upload-dropzone-or"><?php esc_html_e('or', 'hash-form'); ?></span>
58 <div id="hf-editor-upload-label-text-<?php echo absint($field['id']); ?>" class="qq-upload-button"><?php echo isset($field['upload_label']) && $field['upload_label'] ? esc_html($field['upload_label']) : esc_html__('Upload File', 'hash-form'); ?></div>
59 <?php
60 $hint = self::constraints_hint($field, $new_extensions, $max_size, $min_size);
61 if ($hint) {
62 ?>
63 <span class="hf-upload-dropzone-hint"><?php echo esc_html($hint); ?></span>
64 <?php
65 }
66 ?>
67 </div>
68 </div>
69 </div>
70 </div>
71 <?php
72 } else {
73 ?>
74 <div class="hf-file-uploader-wrapper">
75 <div class="hf-file-uploader" id="hf-file-uploader-<?php echo esc_attr($this->html_id()); ?>" data-upload-label="<?php echo isset($field['upload_label']) && $field['upload_label'] ? esc_attr($field['upload_label']) : esc_html__('Upload File', 'hash-form'); ?>" data-extensions="<?php echo esc_attr($new_extensions); ?>" data-extensions-error-message="<?php echo isset($field['extensions_error_message']) ? esc_attr($field['extensions_error_message']) : ''; ?>" data-multiple-uploads="<?php echo isset($field['multiple_uploads']) && $field['multiple_uploads'] == 'on' ? 'true' : 'false'; ?>" data-multiple-uploads-limit="<?php echo isset($field['multiple_uploads']) && $field['multiple_uploads'] == 'on' ? absint($field['multiple_uploads_limit']) : '-1'; ?>" data-multiple-uploads-error-message="<?php echo isset($field['multiple_uploads_error_message']) ? esc_attr($field['multiple_uploads_error_message']) : ''; ?>" data-max-upload-size="<?php echo esc_attr($max_size); ?>" data-min-upload-size="<?php echo esc_attr($min_size); ?>" data-field-uploader-id="<?php echo esc_attr($this->html_id()); ?>">
76 <div class="qq-uploader qq-fake-uploader">
77 <div class="qq-upload-button" style="position: relative; overflow: hidden; direction: ltr;">
78 <?php echo isset($field['upload_label']) && $field['upload_label'] ? esc_attr($field['upload_label']) : esc_html__('Upload File', 'hash-form'); ?>
79 </div>
80 </div>
81 </div>
82
83 <div class="hf-file-preview"></div>
84
85 <input type="hidden" class="hf-uploaded-files" <?php $this->field_attrs(); ?>>
86 <input type="hidden" class="hf-multiple-upload-limit" value="0">
87 </div>
88 <?php
89 }
90 }
91
92 /**
93 * The dropzone icon.
94 *
95 * Twin of UPLOAD_ICON in frontend.js. It has to exist in both because the
96 * uploader script overwrites the element's markup with its own template on
97 * the front end, while the builder renders this PHP instead.
98 */
99 private static function dropzone_icon() {
100 ?>
101 <svg class="hf-upload-dropzone-icon" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
102 <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
103 <polyline points="17 8 12 3 7 8" />
104 <line x1="12" y1="3" x2="12" y2="15" />
105 </svg>
106 <?php
107 }
108
109 /**
110 * "JPG, PNG · up to 10 MB · 5 files max".
111 *
112 * Built from the same field options the uploader is configured with, so the
113 * line cannot promise something the field does not actually allow.
114 */
115 private static function constraints_hint($field, $extensions, $max_size, $min_size = 0) {
116 $parts = array();
117
118 $extensions = array_filter(array_map('trim', explode(',', (string) $extensions)));
119 if ($extensions) {
120 $parts[] = implode(', ', array_map('strtoupper', $extensions));
121 }
122
123 if ($min_size > 0) {
124 /* translators: 1: minimum file size, 2: maximum file size, both formatted, for example "5 KB" and "10 MB". */
125 $parts[] = sprintf(esc_html__('%1$s to %2$s', 'hash-form'), size_format($min_size), size_format($max_size));
126 } elseif ($max_size > 0) {
127 /* translators: %s: maximum file size, already formatted, for example "10 MB". */
128 $parts[] = sprintf(esc_html__('up to %s', 'hash-form'), size_format($max_size));
129 }
130
131 if (isset($field['multiple_uploads']) && $field['multiple_uploads'] == 'on') {
132 $limit = isset($field['multiple_uploads_limit']) ? absint($field['multiple_uploads_limit']) : 0;
133 if ($limit > 0) {
134 /* translators: %d: maximum number of files. */
135 $parts[] = sprintf(esc_html__('%d files max', 'hash-form'), $limit);
136 }
137 }
138
139 return implode(' · ', $parts);
140 }
141
142 public function set_value_before_save($files) {
143 $new_files = array();
144 $files_arr = explode(',', $files);
145 $field = $this->get_field();
146 HashFormBuilder::remove_old_temp_files();
147
148 do_action('hashform_file_before_upload_action', array(
149 'files_arr' => $files_arr,
150 'form_id' => isset($field->form_id) ? $field->form_id : ''
151 ));
152
153 if (apply_filters('hashform_store_local', true)) {
154 /*
155 * The extension is checked again here. What reaches this point is
156 * the name the browser was told to post back, and the temp
157 * directory is a staging area rather than a trusted one, so a file
158 * that got in under a different set of rules does not become
159 * permanent on the strength of having been uploaded once.
160 *
161 * Falls back to the shared list when the field carries no explicit
162 * setting, so a field saved before that option existed is still
163 * held to something rather than to nothing.
164 */
165 $field_extensions = hashform_sanitize_allowed_file_extensions((string) HashFormFields::get_option($field, 'extensions'));
166 $allowed_extensions = array_filter(array_map('trim', explode(',', $field_extensions)));
167
168 if (!$allowed_extensions) {
169 $allowed_extensions = hashform_allowed_file_extensions();
170 }
171
172 foreach ($files_arr as $file) {
173 $file_info = pathinfo($file);
174
175 // pathinfo() drops any directory part; sanitize_file_name() is
176 // idempotent against the name handleUpload() already stored.
177 $file_name = isset($file_info['basename']) ? sanitize_file_name(wp_basename($file_info['basename'])) : '';
178 $extension = isset($file_info['extension']) ? strtolower($file_info['extension']) : '';
179
180 if ('' === $file_name || '' === $extension) {
181 continue;
182 }
183
184 if (!in_array($extension, $allowed_extensions, true)) {
185 continue;
186 }
187
188 $upload_dir = wp_upload_dir();
189
190 $file_path = $upload_dir['basedir'] . HASHFORM_UPLOAD_DIR;
191 $file_url = $upload_dir['baseurl'] . HASHFORM_UPLOAD_DIR;
192 $temp_file_path = $file_path . '/temp/' . $file_name;
193 $to_path = $file_path . '/' . $file_name;
194 $to_url = $file_url . '/' . $file_name;
195
196 if (!file_exists($temp_file_path)) {
197 continue;
198 }
199
200 if (copy($temp_file_path, $to_path)) {
201 $new_files[] = $to_url;
202 }
203 }
204 }
205 return implode(',', apply_filters('hashform_file_upload_filters', $new_files));
206 }
207
208 }
209