| 1 |
<?php |
| 2 |
defined( 'ABSPATH' ) || exit; |
| 3 |
|
| 4 |
/** |
| 5 |
* Shortcode class |
| 6 |
*/ |
| 7 |
class QDBU_QuickDownloadShortCode { |
| 8 |
|
| 9 |
|
| 10 |
public $a; |
| 11 |
public $pid; |
| 12 |
public $attachment_id; |
| 13 |
public $url; |
| 14 |
public $open_new_window; |
| 15 |
public $wait; |
| 16 |
public $download_pid; |
| 17 |
public $color_gb; |
| 18 |
public $panel_color; |
| 19 |
public $icon_id; |
| 20 |
public $custom_file_type_icon; |
| 21 |
public $file_size_icon_id; |
| 22 |
public $custom_file_size_icon; |
| 23 |
public $icon_position; |
| 24 |
public $color_font; |
| 25 |
public $color_icon_dark; |
| 26 |
public $msg; |
| 27 |
public $icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="22" height="22"><path d="M18 11.3l-1-1.1-4 4V3h-1.5v11.3L7 10.2l-1 1.1 6.2 5.8 5.8-5.8zm.5 3.7v3.5h-13V15H4v5h16v-5h-1.5z" /></svg>'; |
| 28 |
public $button_type; |
| 29 |
private $user_role; |
| 30 |
public $validate_msg; |
| 31 |
public $popup_content; |
| 32 |
public $popup_closable; |
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
public function __construct() { |
| 37 |
add_shortcode( 'quick_download_button', array( $this, 'quick_download_button_shortcode' ) ); |
| 38 |
} |
| 39 |
|
| 40 |
/** |
| 41 |
* @usage Add shortcode |
| 42 |
* |
| 43 |
* @param mixed $attr |
| 44 |
* @return void |
| 45 |
*/ |
| 46 |
public function quick_download_button_shortcode( $attr, $content = null ) { |
| 47 |
|
| 48 |
$this->a = shortcode_atts( |
| 49 |
array( |
| 50 |
'title' => 'Download', |
| 51 |
'file_size' => '', |
| 52 |
'url' => '', |
| 53 |
'extension' => '', |
| 54 |
'extension_text' => '0', |
| 55 |
'url_external' => '', |
| 56 |
'open_new_window' => 'false', |
| 57 |
'wait' => 0, |
| 58 |
'color_bg' => null, |
| 59 |
'panel_color' => null, |
| 60 |
'icon_id' => 'default', |
| 61 |
'custom_file_type_icon' => '', |
| 62 |
'file_size_icon_id' => 'folder', |
| 63 |
'custom_file_size_icon' => '', |
| 64 |
'icon_position' => 'left', |
| 65 |
'color_font' => null, |
| 66 |
'color_icon_dark' => 'true', |
| 67 |
'msg' => 'Please wait...', |
| 68 |
'button_type' => 'large', |
| 69 |
'border_width' => null, |
| 70 |
'border_style' => null, |
| 71 |
'border_color' => null, |
| 72 |
'border_radius' => null, |
| 73 |
'align' => null, |
| 74 |
'padding' => null, |
| 75 |
'user_must_be' => '', |
| 76 |
'validate' => false, |
| 77 |
'validate_msg' => '', |
| 78 |
'popup_closable' => '1' |
| 79 |
), |
| 80 |
$attr |
| 81 |
); |
| 82 |
|
| 83 |
/** |
| 84 |
* Filter: qdb_shortcode_atts |
| 85 |
* |
| 86 |
* Modify or extend parsed shortcode attributes before the button is built. |
| 87 |
* Used by Pro: add 'required_product_id', 'download_limit', 'email_gate', etc. |
| 88 |
* |
| 89 |
* @param array $atts Parsed shortcode attributes. |
| 90 |
* @param array $attr Raw attributes passed to the shortcode. |
| 91 |
*/ |
| 92 |
$this->a = apply_filters( 'qdb_shortcode_atts', $this->a, $attr ); |
| 93 |
|
| 94 |
global $post; |
| 95 |
$this->pid = $post->ID; |
| 96 |
$this->download_pid = (int) get_option( 'qdbu_quick_download_button_page_id' ); |
| 97 |
|
| 98 |
$this->attachment_id = attachment_url_to_postid( $this->a['url'] ); //get attachment id from URL |
| 99 |
|
| 100 |
$quick_download_button_url = qdbu_default_url() . '?aid=' . $this->attachment_id; //pass attachment id to plugin download file |
| 101 |
|
| 102 |
|
| 103 |
$this->url = ! empty( $this->a['url'] && strpos( $this->a['url'], site_url()) !== false ) ? $quick_download_button_url : $this->a['url_external']; //if url value is empty set url to external url (url_external) |
| 104 |
|
| 105 |
$this->open_new_window = 'true' === $this->a['open_new_window'] ? 'true' : 'false'; |
| 106 |
|
| 107 |
$this->wait = $this->a['wait'] > 0 ? $this->a['wait'] : 0; |
| 108 |
|
| 109 |
$this->color_gb = null !== $this->a['color_bg'] ? $this->a['color_bg'] : null; |
| 110 |
|
| 111 |
$this->panel_color = null !== $this->a['panel_color'] ? $this->a['panel_color'] : null; |
| 112 |
|
| 113 |
$this->icon_id = sanitize_key( $this->a['icon_id'] ); |
| 114 |
$this->custom_file_type_icon = wp_kses( $this->a['custom_file_type_icon'], array( 'svg' => array( 'xmlns' => true, 'viewbox' => true, 'width' => true, 'height' => true, 'aria-hidden' => true ), 'path' => array( 'd' => true, 'fill' => true ), 'g' => array( 'fill' => true ) ) ); |
| 115 |
$this->file_size_icon_id = sanitize_key( $this->a['file_size_icon_id'] ); |
| 116 |
$this->custom_file_size_icon = wp_kses( $this->a['custom_file_size_icon'], array( 'svg' => array( 'xmlns' => true, 'viewbox' => true, 'width' => true, 'height' => true, 'aria-hidden' => true ), 'path' => array( 'd' => true, 'fill' => true ), 'g' => array( 'fill' => true ) ) ); |
| 117 |
$this->icon_position = in_array( $this->a['icon_position'], array( 'left', 'right' ), true ) ? $this->a['icon_position'] : 'left'; |
| 118 |
$this->popup_content = $content ? do_shortcode( $content ) : null; |
| 119 |
$this->popup_closable = '0' === $this->a['popup_closable'] ? '0' : '1'; |
| 120 |
|
| 121 |
$this->color_font = null !== $this->a['color_font'] ? $this->a['color_font'] : null; |
| 122 |
|
| 123 |
$this->color_icon_dark = 'true' === $this->a['color_icon_dark'] ? 'true' : 'false'; |
| 124 |
|
| 125 |
$this->msg = !empty($this->a['msg']) && '' !== $this->a['msg'] ? $this->a['msg'] : 'Please wait...'; |
| 126 |
|
| 127 |
$this->button_type = !empty($this->a['button_type']) ? $this->a['button_type'] : 'large'; |
| 128 |
|
| 129 |
$this->border_width = !null !== $this->a['border_width'] ? $this->a['border_width'] : null; |
| 130 |
|
| 131 |
$this->border_style = !null !== $this->a['border_style'] ? $this->a['border_style'] : null; |
| 132 |
|
| 133 |
$this->border_color = !null !== $this->a['border_color'] ? $this->a['border_color'] : null; |
| 134 |
|
| 135 |
$this->border_radius = !null !== $this->a['border_radius'] ? $this->a['border_radius'] : null; |
| 136 |
|
| 137 |
$this->padding = !null !== $this->a['padding'] ? $this->a['padding'] : null; |
| 138 |
|
| 139 |
$this->align = !null !== $this->a['align'] ? $this->a['align'] : null; |
| 140 |
|
| 141 |
$this->user_role = '' !== $this->a['user_must_be'] ? trim(strtolower( $this->a['user_must_be'])) : ''; |
| 142 |
|
| 143 |
$this->validate_msg = '' !== $this->a['validate_msg'] ? esc_attr($this->a['validate_msg']) : 'Please contact the admin.'; |
| 144 |
|
| 145 |
|
| 146 |
return $this->generate_button(); |
| 147 |
} |
| 148 |
|
| 149 |
|
| 150 |
/** |
| 151 |
* @Output download button html |
| 152 |
* |
| 153 |
* @return void |
| 154 |
*/ |
| 155 |
public function generate_button() { |
| 156 |
|
| 157 |
$l1_style = 'style="'; |
| 158 |
if(null !== $this->padding) { |
| 159 |
$l1_style .= 'padding-top:' .esc_attr( $this->padding ). 'px;'; |
| 160 |
$l1_style .= 'padding-bottom:' .esc_attr( $this->padding ). 'px;'; |
| 161 |
} |
| 162 |
if(null !== $this->align) { |
| 163 |
$l1_style .= 'padding-top: ' .esc_attr( $this->padding ). 'px;'; |
| 164 |
$l1_style .= 'text-align: ' .esc_attr( $this->align ).';'; |
| 165 |
} |
| 166 |
$l1_style .= '"'; |
| 167 |
|
| 168 |
// Compute btn_id once so it is available throughout generate_button() and to all Pro filters/actions. |
| 169 |
$this->a['btn_id'] = substr( md5( $this->pid . '_' . $this->attachment_id . '_' . $this->a['url_external'] ), 0, 12 ); |
| 170 |
|
| 171 |
$hide_size = '' === $this->a['file_size'] ? ' hide-size' : '' ; |
| 172 |
$hide_file = '' === $this->a['extension'] ? ' hide-file' : '' ; |
| 173 |
|
| 174 |
// Built-in role/login check. |
| 175 |
if ( in_array( $this->user_role, qdbn_get_current_user_roles() ) ) { |
| 176 |
$this->a['validate'] = true; |
| 177 |
} else { |
| 178 |
$this->validate_msg = $this->user_role . ' account required.'; |
| 179 |
} |
| 180 |
if ( 'loggedin' === $this->user_role ) { |
| 181 |
if ( is_user_logged_in() ) { |
| 182 |
$this->a['validate'] = true; |
| 183 |
} else { |
| 184 |
$this->validate_msg = 'You must be logged in to download.'; |
| 185 |
} |
| 186 |
} |
| 187 |
|
| 188 |
/** |
| 189 |
* Filter: qdb_user_can_access |
| 190 |
* |
| 191 |
* Override or extend the access check for the download button. |
| 192 |
* Return array with 'allowed' (bool) and 'message' (string). |
| 193 |
* Used by Pro: WooCommerce purchase gate, email gate, download limit UI. |
| 194 |
* |
| 195 |
* @param array $access { 'allowed' => bool, 'message' => string } |
| 196 |
* @param array $atts Shortcode attributes. |
| 197 |
* @param int $user_id Current user ID (0 for guests). |
| 198 |
*/ |
| 199 |
$access = apply_filters( |
| 200 |
'qdb_user_can_access', |
| 201 |
array( |
| 202 |
'allowed' => $this->a['validate'], |
| 203 |
'message' => $this->validate_msg, |
| 204 |
), |
| 205 |
$this->a, |
| 206 |
get_current_user_id() |
| 207 |
); |
| 208 |
$this->a['validate'] = $access['allowed']; |
| 209 |
$this->validate_msg = $access['message']; |
| 210 |
|
| 211 |
ob_start(); |
| 212 |
?> |
| 213 |
<div className="qdbn-wrapper"> |
| 214 |
<div class="qdbn" |
| 215 |
data-plugin-name="qdbn" |
| 216 |
data-style="<?php echo esc_attr( $this->button_type ); ?>" |
| 217 |
data-file="<?php echo esc_attr( $hide_file ) ;?>" |
| 218 |
data-size="<?php echo esc_attr( $hide_size ) ; ?>" |
| 219 |
data-icon-position="<?php echo esc_attr( $this->icon_position ); ?>" |
| 220 |
<?php |
| 221 |
echo wp_kses( $l1_style, array( |
| 222 |
'style' => array( |
| 223 |
'padding' => array(), |
| 224 |
'text-align' => array(), |
| 225 |
'margin' => array() |
| 226 |
) |
| 227 |
) ); ?> |
| 228 |
> |
| 229 |
<div class="qdbn-download-button-inner"<?php |
| 230 |
$new_styles = array( 'pill', 'card', 'ghost' ); |
| 231 |
if ( in_array( $this->button_type, $new_styles, true ) && ( null !== $this->border_width || null !== $this->border_style || null !== $this->border_color ) ) { |
| 232 |
$c_width = null !== $this->border_width ? esc_attr( $this->border_width ) : '0'; |
| 233 |
$c_style = null !== $this->border_style ? esc_attr( $this->border_style ) : 'solid'; |
| 234 |
$c_color = null !== $this->border_color ? esc_attr( $this->border_color ) : 'transparent'; |
| 235 |
echo ' style="border:' . $c_width . 'px ' . $c_style . ' ' . $c_color . ';"'; |
| 236 |
} |
| 237 |
?>> |
| 238 |
<button class="g-btn f-l" type="button" title="<?php echo esc_attr( $this->a['title'] ); ?>" |
| 239 |
<?php if( $this->a['wait'] > 0 ) : ?> |
| 240 |
data-spinner="<?php echo absint( $this->a['wait'] ); ?>" |
| 241 |
<?php endif; ?> |
| 242 |
<?php if ( '' !== $this->msg ) : ?> |
| 243 |
data-msg="<?php echo esc_attr( $this->msg ); ?>"; |
| 244 |
<?php endif; ?> |
| 245 |
<?php if ('' !== $this->a['user_must_be'] && $this->a['validate']) : ?> |
| 246 |
data-validate="1" |
| 247 |
<?php endif; ?> |
| 248 |
<?php if ('' !== $this->a['user_must_be'] && !$this->a['validate']) : ?> |
| 249 |
data-validate="0" |
| 250 |
data-validate-msg="<?php echo esc_attr($this->validate_msg ); ?>" |
| 251 |
<?php endif; ?> |
| 252 |
data-has-icon-dark="<?php echo esc_attr( $this->color_icon_dark ); ?>" |
| 253 |
<?php if ( $this->popup_content ) : ?>data-qdb-popup="1"<?php endif; ?> |
| 254 |
<?php if ( $this->popup_content && '0' === $this->popup_closable ) : ?>data-qdb-popup-closable="0"<?php endif; ?> |
| 255 |
data-qdb-btn-id="<?php echo esc_attr( $this->a['btn_id'] ); ?>" |
| 256 |
<?php |
| 257 |
if ( empty( $this->a['url_external'] ) && strpos( $this->a['url'], site_url()) !== false) : |
| 258 |
?> |
| 259 |
data-attachment-id="<?php echo esc_attr( $this->add_ids( $this->attachment_id, $this->download_pid ) ); ?>" data-page-id="<?php echo intval( $this->download_pid ); ?>" data-post-id="<?php echo intval( $this->pid ); ?>" |
| 260 |
<?php |
| 261 |
else : |
| 262 |
?> |
| 263 |
data-external-url="<?php echo esc_url( $this->a['url_external'] ); ?>" |
| 264 |
<?php endif; ?> |
| 265 |
data-target-blank="<?php echo esc_attr($this->a['open_new_window']);?>" |
| 266 |
<?php |
| 267 |
/** |
| 268 |
* Filter: qdb_button_data_atts |
| 269 |
* |
| 270 |
* Add extra data-* attributes to the download button element. |
| 271 |
* Used by Pro: email gate injects data-email-gate="1", |
| 272 |
* WooCommerce gate injects data-product-id="X", etc. |
| 273 |
* Return an associative array of attribute name => value. |
| 274 |
* |
| 275 |
* @param array $extra_atts Key/value pairs for data attributes. |
| 276 |
* @param array $atts Shortcode attributes. |
| 277 |
*/ |
| 278 |
$extra_data_atts = apply_filters( 'qdb_button_data_atts', array(), $this->a ); |
| 279 |
foreach ( $extra_data_atts as $attr_name => $attr_value ) { |
| 280 |
echo ' ' . esc_attr( $attr_name ) . '="' . esc_attr( $attr_value ) . '"'; |
| 281 |
} |
| 282 |
?> |
| 283 |
<?php |
| 284 |
$button_styles = 'style="'; |
| 285 |
if ( null !== $this->color_gb && in_array( $this->button_type, array( 'small', 'mid', 'basic', 'pill', 'card', 'ghost' ), true ) ) { |
| 286 |
$button_styles .= 'background: ' .esc_attr( $this->color_gb ). ';'; |
| 287 |
} |
| 288 |
if (null !== $this->color_font) { |
| 289 |
$button_styles .= 'color: ' .esc_attr( $this->color_font ). ';'; |
| 290 |
} |
| 291 |
if(null !== $this->border_radius) { |
| 292 |
$button_styles .= 'border-radius: ' .esc_attr( $this->border_radius ). 'px;'; |
| 293 |
} |
| 294 |
|
| 295 |
// Border on the button only for legacy styles; new styles (pill/card/ghost) get it on the container. |
| 296 |
if ( ! in_array( $this->button_type, array( 'pill', 'card', 'ghost' ), true ) && ( null !== $this->border_width || null !== $this->border_style || null !== $this->border_color ) ) { |
| 297 |
$width = null !== $this->border_width ? esc_attr( $this->border_width ) : '0'; |
| 298 |
$b_style = null !== $this->border_style ? esc_attr( $this->border_style) : 'solid'; |
| 299 |
$color = null !== $this->border_color ? esc_attr( $this->border_color) : 'transparent'; |
| 300 |
$button_styles .= 'border: '.$width.'px '.$b_style. ' '.$color; |
| 301 |
} |
| 302 |
|
| 303 |
$button_styles .= '"'; |
| 304 |
echo wp_kses( $button_styles, array( |
| 305 |
'background' => array( |
| 306 |
'color' => array() |
| 307 |
), |
| 308 |
'color' => array(), |
| 309 |
'border' => array() |
| 310 |
) ); |
| 311 |
?> |
| 312 |
> |
| 313 |
<span class="download-btn-icon"><?php |
| 314 |
if ( 'default' === $this->icon_id ) { |
| 315 |
qdb_sanitize_svg( $this->icon ); |
| 316 |
} else { |
| 317 |
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 318 |
echo qdb_get_builtin_icon( $this->icon_id ); |
| 319 |
} |
| 320 |
?></span> |
| 321 |
<span><?php echo esc_attr( $this->a['title'] ); ?></span> |
| 322 |
</button> |
| 323 |
|
| 324 |
<?php |
| 325 |
$p_styles = 'style="'; |
| 326 |
if ( 'large' === $this->button_type && null !== $this->color_gb || 'mid' === $this->button_type && null !== $this->color_gb ) { |
| 327 |
$p_styles .= 'background: ' .esc_attr( $this->color_gb ). ';'; |
| 328 |
} elseif ( in_array( $this->button_type, array( 'pill', 'card', 'ghost' ), true ) && null !== $this->panel_color ) { |
| 329 |
$p_styles .= 'background: ' . esc_attr( $this->panel_color ) . ';'; |
| 330 |
} |
| 331 |
$p_styles .= '"'; |
| 332 |
|
| 333 |
?> |
| 334 |
<?php if ( '0' !== $this->a['extension'] ) : ?> |
| 335 |
<p class="up" <?php echo $p_styles; ?>> |
| 336 |
<?php if ( $this->custom_file_type_icon ) : ?> |
| 337 |
<?php echo wp_kses( $this->custom_file_type_icon, array( 'svg' => array( 'xmlns' => true, 'viewbox' => true, 'width' => true, 'height' => true, 'aria-hidden' => true ), 'path' => array( 'd' => true, 'fill' => true ), 'g' => array( 'fill' => true ) ) ); ?> |
| 338 |
<?php else : ?> |
| 339 |
<i class="<?php echo esc_attr( $this->qdbu_extension( 'icon' ) ); ?>"></i> |
| 340 |
<?php endif; ?> |
| 341 |
<?php |
| 342 |
if ( '1' === $this->a['extension_text'] ) { |
| 343 |
echo '<span>' . esc_html( $this->qdbu_extension( 'ext' ) ) . '</span>'; |
| 344 |
} |
| 345 |
?> |
| 346 |
</p> |
| 347 |
<?php endif; ?> |
| 348 |
|
| 349 |
<?php |
| 350 |
$have_site_url = strpos( $this->a['url'], site_url() ) === false ? false: true; |
| 351 |
|
| 352 |
if ( '1' === $this->a['file_size'] && $have_site_url ) : |
| 353 |
$file_url = filesize( $this->qdb_convert_url_to_path( $this->a['url'] ) ); |
| 354 |
$file_size = $this->qdb_format_size_units( $file_url ); |
| 355 |
if ( '0 bytes' !== $file_size ) { |
| 356 |
$file_blob_size = $this->qdb_format_size_units( $file_url ); |
| 357 |
$blob_number = explode( ' ', $file_blob_size ); |
| 358 |
$blob_number = $blob_number[0]; |
| 359 |
|
| 360 |
$blob_measure = explode( ' ', $file_blob_size ); |
| 361 |
$blob_measure = $blob_measure[1]; |
| 362 |
} |
| 363 |
/* translators: %1$s is a filesize %2$s is the measurement */ |
| 364 |
$size_icon_html = $this->custom_file_size_icon ? wp_kses( $this->custom_file_size_icon, array( 'svg' => array( 'xmlns' => true, 'viewbox' => true, 'width' => true, 'height' => true, 'aria-hidden' => true ), 'path' => array( 'd' => true, 'fill' => true ), 'g' => array( 'fill' => true ) ) ) : qdb_get_builtin_icon( $this->file_size_icon_id ); |
| 365 |
printf( '<p class="down" %3$s>%4$s<span class="file-size">%1$s %2$s</span></p>', esc_attr( $blob_number ), esc_attr( $blob_measure ), $p_styles, $size_icon_html ); |
| 366 |
|
| 367 |
elseif ( '' !== $this->a['file_size'] ) : |
| 368 |
/* translators: %1$s is a filesize */ |
| 369 |
$size_icon_html = $this->custom_file_size_icon ? wp_kses( $this->custom_file_size_icon, array( 'svg' => array( 'xmlns' => true, 'viewbox' => true, 'width' => true, 'height' => true, 'aria-hidden' => true ), 'path' => array( 'd' => true, 'fill' => true ), 'g' => array( 'fill' => true ) ) ) : qdb_get_builtin_icon( $this->file_size_icon_id ); |
| 370 |
printf( '<p class="down" %2$s>%3$s<span class="file-size"> %1$s </span></p>', esc_attr( $this->a['file_size'] ), $p_styles, $size_icon_html ); |
| 371 |
|
| 372 |
//else : |
| 373 |
?> |
| 374 |
|
| 375 |
<?php endif; ?> |
| 376 |
|
| 377 |
</div> |
| 378 |
</div> |
| 379 |
<quick-download-button-info class="qdb-btn-info"></quick-download-button-info> |
| 380 |
<?php if ( $this->popup_content ) : ?> |
| 381 |
<div class="qdb-popup-src" hidden><?php echo $this->popup_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- trusted: processed by do_shortcode, output by editor ?></div> |
| 382 |
<?php endif; ?> |
| 383 |
<?php |
| 384 |
/** |
| 385 |
* Action: qdb_gate_html |
| 386 |
* |
| 387 |
* Output additional HTML inside the button wrapper (after the button, before closing div). |
| 388 |
* Used by Pro: inject email gate form, passcode input, etc. |
| 389 |
* |
| 390 |
* @param array $atts Shortcode attributes. |
| 391 |
*/ |
| 392 |
do_action( 'qdb_gate_html', $this->a ); |
| 393 |
?> |
| 394 |
</div> |
| 395 |
<?php |
| 396 |
/** |
| 397 |
* Filter: qdb_shortcode_output |
| 398 |
* |
| 399 |
* Modify the final button HTML before it is returned to the page. |
| 400 |
* Used by Pro: wrap with email capture form, modal overlay, etc. |
| 401 |
* |
| 402 |
* @param string $output The complete button HTML. |
| 403 |
* @param array $atts Shortcode attributes. |
| 404 |
*/ |
| 405 |
return apply_filters( 'qdb_shortcode_output', ob_get_clean(), $this->a ); |
| 406 |
} |
| 407 |
|
| 408 |
/** |
| 409 |
* @usage Add file extension text, add icon |
| 410 |
* @param mixed $value |
| 411 |
* @return void |
| 412 |
*/ |
| 413 |
public function qdbu_extension( $value = '' ) { |
| 414 |
$ex = array( |
| 415 |
'ext' => '', |
| 416 |
'icon' => '', |
| 417 |
); |
| 418 |
|
| 419 |
$extension_array = array( 'pdf', 'mp3', 'mov', 'zip', 'txt', 'doc', 'xml', 'mp4', 'ppt' ); |
| 420 |
|
| 421 |
$extension_path = explode( '.', $this->a['url'] ); |
| 422 |
|
| 423 |
$ex['ext'] = end( $extension_path ); |
| 424 |
$ex['ext'] = $ex['ext']; |
| 425 |
|
| 426 |
if ( in_array( strtolower( $ex['ext'] ), $extension_array ) ) { |
| 427 |
$ex['icon'] = 'fi fi-' . strtolower( $ex['ext'] ); |
| 428 |
} else { |
| 429 |
|
| 430 |
$image_array = array( 'jpg', 'jpeg', 'tiff', 'png', 'bmp', 'gif' ); |
| 431 |
if ( in_array( strtolower( $ex['ext'] ), $image_array ) ) { |
| 432 |
$ex['icon'] = 'fi fi-image'; |
| 433 |
} else { |
| 434 |
$ex['icon'] = 'fi fi-file'; |
| 435 |
} |
| 436 |
} |
| 437 |
|
| 438 |
if ( 'icon' === $value ) { |
| 439 |
$value = $ex['icon']; |
| 440 |
} |
| 441 |
if ( 'ext' === $value ) { |
| 442 |
$value = $ex['ext']; |
| 443 |
} |
| 444 |
|
| 445 |
return $value; |
| 446 |
} |
| 447 |
|
| 448 |
|
| 449 |
|
| 450 |
/** |
| 451 |
* @usage Convert URL to path |
| 452 |
* @param mixed $url |
| 453 |
* @return string |
| 454 |
*/ |
| 455 |
public function qdb_convert_url_to_path( $url ) { |
| 456 |
return str_replace( |
| 457 |
wp_get_upload_dir()['baseurl'], |
| 458 |
wp_get_upload_dir()['basedir'], |
| 459 |
$url |
| 460 |
); |
| 461 |
} |
| 462 |
|
| 463 |
|
| 464 |
|
| 465 |
/** |
| 466 |
* @usage Get file size |
| 467 |
* |
| 468 |
* @param mixed $bytes |
| 469 |
* @return string |
| 470 |
*/ |
| 471 |
public function qdb_format_size_units( $bytes ) { |
| 472 |
if ( $bytes >= 1073741824 ) { |
| 473 |
$bytes = number_format( $bytes / 1073741824, 2 ) . ' GB'; |
| 474 |
} elseif ( $bytes >= 1048576 ) { |
| 475 |
$bytes = number_format( $bytes / 1048576, 2 ) . ' MB'; |
| 476 |
} elseif ( $bytes >= 1024 ) { |
| 477 |
$bytes = number_format( $bytes / 1024, 2 ) . ' KB'; |
| 478 |
} elseif ( $bytes > 1 ) { |
| 479 |
$bytes = $bytes . ' bytes'; |
| 480 |
} elseif ( 1 === $bytes ) { |
| 481 |
$bytes = $bytes . ' byte'; |
| 482 |
} else { |
| 483 |
$bytes = '0 bytes'; |
| 484 |
} |
| 485 |
|
| 486 |
return $bytes; |
| 487 |
} |
| 488 |
|
| 489 |
|
| 490 |
/** |
| 491 |
* @usage add attachment ID + download page id, use this to disguise real attachment ID when view from browser inspect |
| 492 |
* @param mixed $num1 |
| 493 |
* @param mixed $num2 |
| 494 |
* @return int |
| 495 |
*/ |
| 496 |
public static function add_ids( $num1, $num2 ) { |
| 497 |
return intval( $num1 + $num2 ); |
| 498 |
} |
| 499 |
} |
| 500 |
|
| 501 |
/** |
| 502 |
* Return an inline SVG string for a built-in icon ID. |
| 503 |
* Used by the shortcode to match the Gutenberg block's icon set. |
| 504 |
* |
| 505 |
* @param string $id Icon ID (matches QDB_DOWNLOAD_ICONS / QDB_SIZE_ICONS in JS). |
| 506 |
* @param int $size Icon size in px. |
| 507 |
* @return string SVG HTML string, already escaped for output. |
| 508 |
*/ |
| 509 |
function qdb_get_builtin_icon( $id, $size = 20 ) { |
| 510 |
$paths = array( |
| 511 |
'default' => 'M18 11.3l-1-1.1-4 4V3h-1.5v11.3L7 10.2l-1 1.1 6.2 5.8 5.8-5.8zm.5 3.7v3.5h-13V15H4v5h16v-5h-1.5z', |
| 512 |
'cloud' => 'M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM17 13l-5 5-5-5h3V9h4v4h3z', |
| 513 |
'circle' => 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 5h2v6h3l-4 4-4-4h3V7z', |
| 514 |
'file-dl' => 'M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z', |
| 515 |
'inbox' => 'M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5v-3h3.56c.69 1.19 1.97 2 3.45 2s2.75-.81 3.45-2H19v3zm0-5h-4.99c0 1.1-.9 1.99-2 1.99S10 15.1 10 14H5V5h14v9z', |
| 516 |
'save' => 'M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z', |
| 517 |
'bolt' => 'M7 2v11h3v9l7-12h-4l4-8z', |
| 518 |
'folder' => 'M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z', |
| 519 |
'archive' => 'M20.54 5.23l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6.02 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5L6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z', |
| 520 |
'info' => 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z', |
| 521 |
'chip' => 'M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9h-4v4h-2v-4H9V9h4V5h2v4h4v2z', |
| 522 |
); |
| 523 |
$id = isset( $paths[ $id ] ) ? $id : 'default'; |
| 524 |
return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="' . absint( $size ) . '" height="' . absint( $size ) . '" aria-hidden="true"><path fill="currentColor" d="' . esc_attr( $paths[ $id ] ) . '"/></svg>'; |
| 525 |
} |
| 526 |
|
| 527 |
/** |
| 528 |
* Sanitize SVG |
| 529 |
*/ |
| 530 |
|
| 531 |
function qdb_sanitize_svg( $svg ) { |
| 532 |
$kses_defaults = wp_kses_allowed_html( 'post' ); |
| 533 |
|
| 534 |
$svg_args = array( |
| 535 |
'svg' => array( |
| 536 |
'class' => true, |
| 537 |
'aria-hidden' => true, |
| 538 |
'aria-labelledby' => true, |
| 539 |
'role' => true, |
| 540 |
'xmlns' => true, |
| 541 |
'width' => true, |
| 542 |
'height' => true, |
| 543 |
'viewbox' => true // <= Must be lower case! |
| 544 |
), |
| 545 |
'g' => array( 'fill' => true ), |
| 546 |
'title' => array( 'title' => true ), |
| 547 |
'path' => array( |
| 548 |
'd' => true, |
| 549 |
'fill' => true |
| 550 |
) |
| 551 |
); |
| 552 |
|
| 553 |
$allowed_tags = array_merge( $kses_defaults, $svg_args ); |
| 554 |
|
| 555 |
echo wp_kses( $svg, $allowed_tags ); |
| 556 |
} |
| 557 |
|
| 558 |
|
| 559 |
|
| 560 |
/** |
| 561 |
* Get the current user's role. |
| 562 |
* @return array |
| 563 |
*/ |
| 564 |
|
| 565 |
function qdbn_get_current_user_roles() { |
| 566 |
|
| 567 |
if( is_user_logged_in() ) { |
| 568 |
|
| 569 |
$user = wp_get_current_user(); |
| 570 |
|
| 571 |
$roles = ( array ) $user->roles; |
| 572 |
|
| 573 |
return $roles; // This will returns an array |
| 574 |
|
| 575 |
} else { |
| 576 |
|
| 577 |
return array(); |
| 578 |
|
| 579 |
} |
| 580 |
|
| 581 |
} |
| 582 |
|
| 583 |
|
| 584 |
function qdbn_get_user_rolls() { |
| 585 |
$data = ['Nothing','Logged in']; |
| 586 |
$roles = wp_roles()->get_names(); |
| 587 |
|
| 588 |
foreach( $roles as $role ) { |
| 589 |
array_push($data, strtolower( translate_user_role( $role ) )); |
| 590 |
} |
| 591 |
return $data; |
| 592 |
} |
| 593 |
|
| 594 |
|
| 595 |
/** |
| 596 |
* Shortcode: [quick_download_button_group] |
| 597 |
* |
| 598 |
* Wraps multiple [quick_download_button] shortcodes in a flex row. |
| 599 |
* |
| 600 |
* Attributes: |
| 601 |
* layout - 'horizontal' (default) or 'stack' |
| 602 |
* stack_on_mobile - 'true' (default) or 'false' |
| 603 |
* alignment - 'left' (default), 'center', or 'right' |
| 604 |
* gap - gap between buttons in px (default: 12) |
| 605 |
* |
| 606 |
* Example: |
| 607 |
* [quick_download_button_group alignment="center" gap="16"] |
| 608 |
* [quick_download_button url="..." title="Download v1"] |
| 609 |
* [quick_download_button url="..." title="Download v2"] |
| 610 |
* [/quick_download_button_group] |
| 611 |
*/ |
| 612 |
function qdbu_button_group_shortcode( $atts, $content = null ) { |
| 613 |
$atts = shortcode_atts( |
| 614 |
array( |
| 615 |
'layout' => 'horizontal', |
| 616 |
'stack_on_mobile' => 'true', |
| 617 |
'alignment' => 'left', |
| 618 |
'gap' => '12', |
| 619 |
), |
| 620 |
$atts |
| 621 |
); |
| 622 |
|
| 623 |
$allowed_layouts = array( 'horizontal', 'stack' ); |
| 624 |
$allowed_alignment = array( 'left', 'center', 'right' ); |
| 625 |
$align_map = array( 'left' => 'flex-start', 'center' => 'center', 'right' => 'flex-end' ); |
| 626 |
|
| 627 |
$layout = in_array( $atts['layout'], $allowed_layouts, true ) ? $atts['layout'] : 'horizontal'; |
| 628 |
$alignment = in_array( $atts['alignment'], $allowed_alignment, true ) ? $atts['alignment'] : 'left'; |
| 629 |
$gap = absint( $atts['gap'] ); |
| 630 |
|
| 631 |
$classes = 'qdb-btn-row qdb-btn-row--' . $layout; |
| 632 |
if ( 'true' === $atts['stack_on_mobile'] ) { |
| 633 |
$classes .= ' qdb-btn-row--mobile-stack'; |
| 634 |
} |
| 635 |
$classes .= ' qdb-btn-row--align-' . $alignment; |
| 636 |
|
| 637 |
if ( 'stack' === $layout ) { |
| 638 |
$style = 'gap:' . $gap . 'px;align-items:' . $align_map[ $alignment ] . ';'; |
| 639 |
} else { |
| 640 |
$style = 'gap:' . $gap . 'px;justify-content:' . $align_map[ $alignment ] . ';align-items:flex-start;'; |
| 641 |
} |
| 642 |
|
| 643 |
return '<div class="' . esc_attr( $classes ) . '" style="' . esc_attr( $style ) . '">' |
| 644 |
. do_shortcode( $content ) |
| 645 |
. '</div>'; |
| 646 |
} |
| 647 |
add_shortcode( 'quick_download_button_group', 'qdbu_button_group_shortcode' ); |
| 648 |
|
| 649 |
|
| 650 |
|
| 651 |
|
| 652 |
|
| 653 |
|
| 654 |
|
| 655 |
|
| 656 |
|