PluginProbe ʕ •ᴥ•ʔ
Download Manager / 3.3.66
Download Manager v3.3.66
3.3.66 3.3.65 3.3.64 3.3.63 3.3.62 3.3.61 3.3.60 3.3.59 3.3.58 3.3.57 3.3.56 trunk 2.1.3 2.3.0 2.5.96 2.5.97 2.6.2 2.6.96 2.8.3 2.9.99 3.0.4 3.1.05 3.1.07 3.1.08 3.1.11 3.1.12 3.1.14 3.1.17 3.1.18 3.1.22 3.1.23 3.1.24 3.1.25 3.1.26 3.1.27 3.1.28 3.2.04 3.2.13 3.2.14 3.2.16 3.2.18 3.2.19 3.2.21 3.2.22 3.2.23 3.2.24 3.2.25 3.2.27 3.2.28 3.2.29 3.2.30 3.2.31 3.2.32 3.2.33 3.2.34 3.2.35 3.2.37 3.2.38 3.2.39 3.2.40 3.2.41 3.2.42 3.2.43 3.2.44 3.2.45 3.2.46 3.2.47 3.2.48 3.2.49 3.2.50 3.2.51 3.2.52 3.2.53 3.2.54 3.2.55 3.2.56 3.2.57 3.2.58 3.2.59 3.2.60 3.2.61 3.2.63 3.2.64 3.2.65 3.2.66 3.2.67 3.2.68 3.2.69 3.2.70 3.2.71 3.2.72 3.2.73 3.2.74 3.2.75 3.2.76 3.2.77 3.2.78 3.2.79 3.2.80 3.2.81 3.2.82 3.2.83 3.2.84 3.2.85 3.2.86 3.2.87 3.2.88 3.2.89 3.2.90 3.2.91 3.2.92 3.2.93 3.2.94 3.2.95 3.2.96 3.2.97 3.2.98 3.2.99 3.3.00 3.3.01 3.3.02 3.3.03 3.3.04 3.3.05 3.3.06 3.3.07 3.3.08 3.3.09 3.3.10 3.3.11 3.3.12 3.3.13 3.3.14 3.3.15 3.3.16 3.3.17 3.3.18 3.3.19 3.3.20 3.3.21 3.3.22 3.3.23 3.3.24 3.3.25 3.3.26 3.3.27 3.3.28 3.3.29 3.3.30 3.3.31 3.3.32 3.3.33 3.3.34 3.3.35 3.3.36 3.3.37 3.3.38 3.3.39 3.3.40 3.3.41 3.3.42 3.3.43 3.3.44 3.3.45 3.3.46 3.3.47 3.3.48 3.3.49 3.3.50 3.3.51 3.3.52 3.3.53 3.3.54 3.3.55
download-manager / src / Package / PackageController.php
download-manager / src / Package Last commit date
views 3 weeks ago FileList.php 5 years ago Hooks.php 3 years ago Package.php 1 year ago PackageController.php 5 days ago PackageLocks.php 2 weeks ago PackageTemplate.php 5 years ago RestAPI.php 5 days ago Shortcodes.php 1 week ago
PackageController.php
2823 lines
1 <?php
2
3
4 namespace WPDM\Package;
5
6
7 use WPDM\__\__;
8 use WPDM\__\Crypt;
9 use WPDM\__\FileSystem;
10 use WPDM\__\Messages;
11 use WPDM\__\Query;
12 use WPDM\__\Session;
13 use WPDM\__\TempStorage;
14 use WPDM\__\UI;
15
16 class PackageController extends PackageTemplate {
17
18
19 public $ID;
20 public $title;
21 public $description;
22 public $excerpt;
23 /**
24 * @var FileList
25 */
26 public $fileList;
27 public $post_status;
28 public $version;
29 public $publish_date;
30 public $publish_date_timestamp;
31 public $update_date;
32 public $update_date_timestamp;
33 public $avail_date;
34 public $expire_date;
35 public $link_label;
36 public $download_count;
37 public $view_count;
38 public $access;
39 public $author;
40 public $quota;
41 public $icon;
42 public $package_size;
43 public $package;
44 public $shortCodes;
45 public $packageData = [];
46 public $files = [];
47 public $restAPI;
48 public $templateDir;
49
50 public $post_author;
51 public $post_date;
52 public $post_content;
53 public $post_title;
54 public $post_excerpt;
55 public $file_count;
56 public $thumb;
57 public $preview;
58 public $featured_image;
59 public $file_type_icon;
60 public $download_url;
61 public $download_link;
62 public $download_link_extended;
63 public $avatar;
64 public $author_profile_url;
65 public $author_name;
66 public $page_url;
67 public $page_link;
68 public $page_url_qr;
69 public $btnclass;
70 public $avatar_url;
71 public $post_modified;
72
73
74 function __construct( $ID = null ) {
75 parent::__construct();
76
77 $this->templateDir = __DIR__ . '/views/';
78 $this->shortCodes = new Shortcodes();
79 new Hooks();
80
81 new RestAPI();
82
83 add_action("wp_ajax_wpdm_view_count", [$this, 'addViewCount']);
84
85 global $post;
86 if ( ! $ID && is_object( $post ) && $post->post_type == 'wpdmpro' ) {
87 $ID = $post->ID;
88 }
89 $this->ID = $ID;
90
91 }
92
93 function prepare( $ID = null, $template = null, $template_type = 'page' ) {
94 global $post;
95
96 if ( ! $ID ) {
97 $ID = $this->ID;
98 }
99 if ( ! $ID && isset( $post->ID ) && get_post_type( $post ) == 'wpdmpro' ) {
100 $ID = $post->ID;
101 }
102 if ( ! $ID ) {
103 $this->packageData = array( 'error' => __( "ID missing!", "download-manager" ) );
104
105 return $this;
106 }
107
108 if ( ! is_object( $post ) || $post->ID != $ID ) {
109 $_post = get_post( $ID );
110 if ( get_class( $_post ) != 'WP_Post' ) {
111 return new \WP_Error( 'broke', __( "Invalid Package ID!", "download-manager" ) );
112 }
113 $post_vars = (array) $_post;
114 } else {
115 $post_vars = (array) $post;
116 }
117
118 $ID = $post_vars['ID'];
119
120 // Never run stripcslashes() on stored input: it decodes C-style escapes
121 // ( \x3C etc. ) back into active markup after save-time KSES has already run.
122 $post_vars['title'] = esc_html( $post_vars['post_title'] );
123
124 $template_tags = $this->parseTemplate( $template, $ID, $template_type );
125
126 if(in_array('description', $template_tags)) {
127 $post_vars['description'] = str_replace( "[wpdm", "[__wpdm", wp_kses_post( $post_vars['post_content'] ) );
128 $post_vars['description'] = wpautop( stripslashes( $post_vars['description'] ) );
129
130 if($template_type === 'page') {
131 global $wp_embed;
132 $post_vars['description'] = $wp_embed->autoembed( $post_vars['description'] );
133 if ( ! has_shortcode( $post_vars['description'], 'wpdm_package' ) ) {
134 $post_vars['description'] = do_shortcode( stripslashes( $post_vars['description'] ) );
135 }
136 }
137 } else {
138 $post_vars['description'] = wpautop(strip_shortcodes( $post_vars['post_content'] ));
139 }
140
141 $post_vars['excerpt'] = wpautop( wp_kses_post( $post_vars['post_excerpt'] ) );
142 $author = get_user_by( 'id', $post_vars['post_author'] );
143 if ( is_object( $author ) ) {
144 $post_vars['author_name'] = $author->display_name;
145 }
146 $post_vars['author_profile_url'] = get_author_posts_url( $post_vars['post_author'] );
147 if ( is_object( $author ) ) {
148 $post_vars['avatar_url'] = get_avatar_url( $author->user_email );
149 }
150 if ( is_object( $author ) ) {
151 $post_vars['avatar'] = get_avatar( $author->user_email, 96 );
152 }
153
154 $template_tags = $this->parseTemplate( $template, $ID, $template_type );
155
156 //Featured Image
157 $post_vars['preview'] = $post_vars['thumb'] = "";
158 if ( has_post_thumbnail( $ID ) ) {
159 $src = wp_get_attachment_image_src( get_post_thumbnail_id( $ID ), 'full', false );
160
161 $post_vars['preview'] = is_array($src) ? $src['0'] : '';
162 $post_vars['featured_image'] = get_the_post_thumbnail( $ID, 'full' );
163 if ( in_array( 'thumb', $template_tags ) ) {
164 $post_vars['thumb'] = get_the_post_thumbnail( $ID );
165 }
166 }
167 if ( in_array( 'author_package_count', $template_tags ) ) {
168 $post_vars['author_package_count'] = count_user_posts( $post_vars['post_author'], "wpdmpro" );
169 }
170
171 if ( in_array( 'create_date', $template_tags ) ) {
172 $post_vars['create_date'] = get_the_date( '', $ID );
173 }
174
175 if ( in_array( 'update_date', $template_tags ) ) {
176 $post_vars['update_date'] = date_i18n( get_option( 'date_format' ), strtotime( $post_vars['post_modified'] ) );
177 }
178
179 if ( in_array( 'categories', $template_tags ) ) {
180 $post_vars['categories'] = get_the_term_list( $ID, 'wpdmcategory', '', ', ', '' );
181 }
182
183 if ( in_array( 'category', $template_tags ) ) {
184 $cats = get_the_terms( $ID, 'wpdmcategory' );
185 if ( is_array( $cats ) && count( $cats ) > 0 ) {
186 $post_vars['category'] = $cats[0]->name;
187 }
188 }
189
190 $post_vars['comment_count'] = wp_count_comments( $ID )->approved;
191
192 if ( in_array( 'cats_class', $template_tags ) ) {
193 $cats = wp_get_post_terms( $ID, 'wpdmcategory' );
194 $post_vars['cats_class'] = "";
195 foreach ( $cats as $cat ) {
196 $post_vars['cats_class'] .= " wpdmcat-{$cat->id} {$cat->slug}";
197 }
198 }
199
200 $data = $this->metaData( $post_vars['ID'] );
201
202 if ( is_array( $data ) ) {
203 $post_vars = array_merge( $data, $post_vars );
204 }
205
206 if ( ! isset( $post_vars['files'] ) || ! is_array( $post_vars['files'] ) ) {
207 $post_vars['files'] = self::getFiles( $ID, true );
208 }
209
210 if ( in_array( 'file_count', $template_tags ) ) {
211 $post_vars['file_count'] = count( $post_vars['files'] );
212 }
213
214 if ( in_array( 'play_button', $template_tags ) ) {
215 $post_vars['play_button'] = self::audioPlayer( $post_vars );
216 }
217
218
219 $post_vars['link_label'] = isset( $post_vars['link_label'] ) ? esc_attr( $post_vars['link_label'] ) : esc_attr__( "Download", "download-manager" );
220 $post_vars['page_url'] = get_permalink( $post_vars['ID'] );
221 $post_vars['page_link'] = "<a href='" . $post_vars['page_url'] . "'>{$post_vars['title']}</a>";
222 $post_vars['page_url_qr'] = "<img class='wpdm-qr-code wpdm-qr-code{$post_vars['ID']}' style='max-width: 250px' src='https://chart.googleapis.com/chart?cht=qr&chs=450x450&choe=UTF-8&chld=H|0&chl=" . esc_attr( $post_vars['page_url'] ) . "' alt='" . esc_attr( $post_vars['title'] ) . "' />";
223
224
225 if ( ! isset( $post_vars['btnclass'] ) ) {
226 $post_vars['btnclass'] = wpdm_download_button_style( null, $ID );
227 }
228
229 if ( in_array( 'tags', $template_tags ) ) {
230 $tags = wp_get_post_terms( $post_vars['ID'], WPDM_TAG );
231 $taghtml = "";
232 if ( is_array( $tags ) ) {
233 foreach ( $tags as $tag ) {
234 $taghtml .= "<a class='btn btn-secondary btn-xs' style='margin:0 5px 5px 0' href=\""
235 . get_tag_link( $tag->term_id )
236 . "\"><i class='fa fa-tag'></i> &nbsp; " . $tag->name . "</a> &nbsp;";
237 }
238 }
239 $post_vars['tags'] = $taghtml;
240 }
241
242 if ( in_array( 'file_ext', $template_tags ) ) {
243 $post_vars['files'] = isset( $post_vars['files'] ) && is_array( $post_vars['files'] ) ? $post_vars['files'] : self::getFiles( $ID );
244 if ( count( $post_vars['files'] ) > 1 ) {
245 $post_vars['file_ext'] = 'zip';
246 }
247 if ( is_array( $post_vars['files'] ) && count( $post_vars['files'] ) == 1 ) {
248 $tmpdata = $post_vars['files'];
249 $tmpdata = array_shift( $tmpdata );
250 $tmpdata = explode( ".", $tmpdata );
251 $post_vars['file_ext'] = end( $tmpdata );
252 }
253 }
254
255 if ( in_array( 'file_size', $template_tags ) ) {
256 $post_vars['file_size'] = self::Size( $post_vars['ID'] );
257 }
258
259 if ( in_array( 'audio_player_single', $template_tags ) ) {
260 $post_vars['audio_player_single'] = self::audioPlayer( $post_vars, true );
261 }
262
263 if ( array_intersect( $template_tags, array(
264 'youtube_player',
265 'youtube_thumb_0',
266 'youtube_thumb_1',
267 'youtube_thumb_2',
268 'youtube_thumb_3'
269 ) ) ) {
270 $post_vars['files'] = isset( $post_vars['files'] ) && is_array( $post_vars['files'] ) ? $post_vars['files'] : self::getFiles( $ID );
271 $tmplfile = $post_vars['files'];
272 $tmpfile = is_array( $tmplfile ) && count( $tmplfile ) > 0 ? array_shift( $tmplfile ) : '';
273 if ( strpos( $tmpfile, 'youtu' ) ) {
274 if ( preg_match( '/youtu\.be\/([^\/]+)/', $tmpfile, $match ) ) {
275 $vid = $match[1];
276 } else if ( preg_match( '/watch\?v=([^\/]+)/', $tmpfile, $match ) ) {
277 $vid = $match[1];
278 }
279 if ( isset( $vid ) ) {
280 $post_vars['youtube_thumb_0'] = '<img src="https://img.youtube.com/vi/' . $vid . '/0.jpg" alt="Thumb 0" />';
281 $post_vars['youtube_thumb_1'] = '<img src="https://img.youtube.com/vi/' . $vid . '/1.jpg" alt="Thumb 1" />';
282 $post_vars['youtube_thumb_2'] = '<img src="https://img.youtube.com/vi/' . $vid . '/2.jpg" alt="Thumb 2" />';
283 $post_vars['youtube_thumb_3'] = '<img src="https://img.youtube.com/vi/' . $vid . '/3.jpg" alt="Thumb 3" />';
284 $post_vars['youtube_player'] = '<iframe width="1280" height="720" src="https://www.youtube.com/embed/' . $vid . '" frameborder="0" allowfullscreen></iframe>';
285 }
286 }
287 }
288
289 if ( array_intersect( array( 'file_type_icon', 'icon' ), $template_tags ) ) {
290 $post_vars['files'] = isset( $post_vars['files'] ) && is_array( $post_vars['files'] ) ? $post_vars['files'] : self::getFiles( $ID );
291 if ( is_array( $post_vars['files'] ) ) {
292 $tifn = $ifn = @end( $post_vars['files'] );
293 $ifn = @explode( '.', $ifn );
294 $ifn = @end( $ifn );
295 if ( strlen( $ifn ) > 4 && strstr( $tifn, "://" ) ) {
296 $ifn = 'web';
297 }
298 if ( strlen( $ifn ) > 4 && ! strstr( $tifn, "://" ) ) {
299 $ifn = 'unknown';
300 }
301 } else {
302 $ifn = 'unknown';
303 }
304
305 $post_vars['file_type_icon'] = '<img class="wpdm_icon" alt="' . __( "Icon", "download-manager" ) . '" src="' . FileSystem::fileTypeIcon( ( @count( $post_vars['files'] ) <= 1 ? $ifn : 'zip' ) ) . '" />';
306
307 if ( ! isset( $post_vars['icon'] ) || $post_vars['icon'] == '' ) {
308 $post_vars['icon'] = $post_vars['file_type_icon'];
309 } else if ( ! strpos( $post_vars['icon'], '://' ) ) {
310 $post_vars['icon'] = '<img class="wpdm_icon" alt="' . __( "Icon", "download-manager" ) . '" src="' . plugins_url( str_replace( 'download-manager/file-type-icons/', 'download-manager/assets/file-type-icons/', $post_vars['icon'] ) ) . '" />';
311 } else if ( ! strpos( $post_vars['icon'], ">" ) ) {
312 $post_vars['icon'] = '<img class="wpdm_icon" alt="' . __( "Icon", "download-manager" ) . '" src="' . str_replace( 'download-manager/file-type-icons/', 'download-manager/assets/file-type-icons/', $post_vars['icon'] ) . '" />';
313 }
314
315 }
316
317
318 $post_vars['link_label'] = apply_filters( 'wpdm_button_image', $post_vars['link_label'], $post_vars, $template_type );
319
320 $post_vars['link_label'] = $post_vars['link_label'] ? $post_vars['link_label'] : __( "Download", "download-manager" );
321
322 if($this->hasAttachment($ID)) {
323 $post_vars['download_url'] = $this->getDownloadURL( $post_vars['ID'] );
324 $post_vars['download_link_popup'] =
325 $post_vars['download_link_extended'] =
326 $post_vars['download_link'] = (int) get_option( '__wpdm_mask_dlink', 1 ) == 1 ? "<a class='wpdm-download-link download-on-click {$post_vars['btnclass']}' rel='nofollow' href='#' data-downloadurl=\"{$post_vars['download_url']}\">{$post_vars['link_label']}</a>" : "<a class='wpdm-download-link {$post_vars['btnclass']}' rel='nofollow' href='{$post_vars['download_url']}'>{$post_vars['link_label']}</a>";
327 } else {
328 $post_vars['download_url'] = '#'.__('No file attached', WPDM_TEXT_DOMAIN);
329 $post_vars['download_link_popup'] =
330 $post_vars['download_link_extended'] =
331 $post_vars['download_link'] = UI::div('<i class="fa-solid fa-file-circle-xmark mr-3"></i>'.__('No file attached', WPDM_TEXT_DOMAIN), 'alert alert-danger d-inline-block px-3 py-2');
332 }
333
334 $limit_over = 0;
335 $alert_size = ( $template_type == 'link' ) ? 'alert-sm' : '';
336
337 $loginmsg = Messages::login_required( $post_vars['ID'] );
338
339 //Download limit is over
340 if ( self::userDownloadLimitExceeded( $post_vars['ID'] ) ) {
341 $limit_over = 1;
342 $limit_msg = Messages::download_limit_exceeded( $post_vars['ID'] );
343 $post_vars['download_url'] = '#';
344 $post_vars['link_label'] = $limit_msg;
345 $post_vars['download_link_popup'] =
346 $post_vars['download_link_extended'] =
347 $post_vars['download_link'] = $post_vars['link_label'];
348 } //Item is expired
349 else if ( isset( $post_vars['expire_date'] ) && $post_vars['expire_date'] != "" && strtotime( $post_vars['expire_date'] ) < time() ) {
350 $post_vars['download_url'] = '#';
351 $post_vars['link_label'] = __( "Download was expired on", "download-manager" ) . " " . date_i18n( get_option( 'date_format' ) . " h:i A", strtotime( $post_vars['expire_date'] ) );
352 $post_vars['download_link'] =
353 $post_vars['download_link_extended'] =
354 $post_vars['download_link_popup'] = "<div class='alert alert-warning {$alert_size}' data-title='" . __( "DOWNLOAD ERROR:", "download-manager" ) . "'>{$post_vars['link_label']}</div>";
355 } //Not available yet
356 else if ( isset( $post_vars['publish_date'] ) && $post_vars['publish_date'] != '' && strtotime( $post_vars['publish_date'] ) > time() ) {
357 $post_vars['download_url'] = '#';
358 $post_vars['link_label'] = __( "Download will be available from ", "download-manager" ) . " " . date_i18n( get_option( 'date_format' ) . " h:i A", strtotime( $post_vars['publish_date'] ) );
359 $post_vars['download_link'] =
360 $post_vars['download_link_extended'] =
361 $post_vars['download_link_popup'] = "<div class='alert alert-warning {$alert_size}' data-title='" . __( "DOWNLOAD ERROR:", "download-manager" ) . "'>{$post_vars['link_label']}</div>";
362 } //User is not allowed
363 else if ( is_user_logged_in() && ! self::userCanAccess( $post_vars['ID'] ) ) {
364 $post_vars['download_url'] = '#';
365 $post_vars['link_label'] = stripslashes( get_option( '__wpdm_permission_denied_msg' ) );
366 $post_vars['link_label'] = $post_vars['link_label'] !== '' ? $post_vars['link_label'] : __( 'You are not allowed to download.', 'download-manager' );
367 $post_vars['download_link'] =
368 $post_vars['download_link_extended'] =
369 $post_vars['download_link_popup'] = "<div class='alert alert-danger {$alert_size}' data-title='" . __( "DOWNLOAD ERROR:", "download-manager" ) . "'>{$post_vars['link_label']}</div>";
370 } //User is not logged in and guest access is not allowed
371 else if ( ! is_user_logged_in() && ! self::userCanAccess( $post_vars['ID'] ) ) {
372 $packurl = get_permalink( $post_vars['ID'] );
373 $loginform = WPDM()->user->login->form( array( 'redirect' => $packurl ) );
374 $post_vars['download_url'] = WPDM()->user->login->url( __::valueof($_SERVER, 'REQUEST_URI', ['validate' => 'txt']) );
375 $post_vars['download_link'] =
376 $post_vars['download_link_extended'] =
377 $post_vars['download_link_popup'] = stripcslashes( str_replace( array(
378 "[loginform]",
379 "[this_url]",
380 "[package_url]"
381 ), array( $loginform, __::valueof($_SERVER, 'REQUEST_URI', ['validate' => 'txt']), $packurl ), $loginmsg ) );
382 $post_vars['download_link'] =
383 $post_vars['download_link_extended'] =
384 $post_vars['download_link_popup'] = get_option( '__wpdm_login_form', 0 ) == 1 ? $loginform : $post_vars['download_link'];
385 } //PACKAGE is locked
386 else if ( $this->isLocked( $post_vars['ID'] ) ) {
387 $post_vars['download_url'] = '#';
388 $post_vars['download_link'] = $post_vars['download_link_popup'] = "<a href='#unlock' class='wpdm-download-link wpdm-download-locked {$post_vars['btnclass']}' data-package='{$post_vars['ID']}'>{$post_vars['link_label']}</a>"; //self::activeLocks($post_vars);
389 $post_vars['download_link_extended'] = self::activeLocks( $post_vars['ID'], array( 'embed' => 1 ) );
390 //$post_vars['download_link_popup'] = self::activeLocks($post_vars, array('popstyle' => 'popup'));
391 }
392
393 if ( isset( $data['terms_lock'] ) && $data['terms_lock'] != 0 && ( ! function_exists( 'wpdmpp_effective_price' ) || wpdmpp_effective_price( $post_vars['ID'] ) == 0 ) && $limit_over == 0 && self::userCanAccess( $post_vars['ID'] ) ) {
394 //$data['terms_conditions'] = wpautop(strip_tags($data['terms_conditions'], "<p><br><a><strong><b><i>"));
395 /*$data['terms_conditions'] = wpautop(wpdm_escs(get_post_meta($post_vars['ID'], '__wpdm_terms_conditions', true)));
396 $data['terms_title'] = wpdm_escs(get_post_meta($post_vars['ID'], '__wpdm_terms_title', true));
397 $data['terms_title'] = !isset($data['terms_title']) || $data['terms_title'] == '' ? __("Terms and Conditions", 'download-manager') : sanitize_text_field($data['terms_title']);
398 $data['terms_check_label'] = !isset($data['terms_check_label']) || $data['terms_check_label'] == '' ? __("I Agree With Terms and Conditions", 'download-manager') : sanitize_text_field($data['terms_check_label']);
399 if (!self::isLocked($post_vars)) {
400 $post_vars['download_link_popup'] = $post_vars['download_link'] = "<a href='#unlock' class='wpdm-download-link wpdm-download-locked {$post_vars['btnclass']}' data-package='{$post_vars['ID']}'>{$post_vars['link_label']}</a>";
401 }
402 //$data['terms_conditions'] = wpautop(strip_tags($data['terms_conditions'], "<p><br><a><strong><b><i>"));
403 $data['terms_conditions'] = wpautop(wpdm_escs($data['terms_conditions']));*/
404
405 $terms_page = (int) get_post_meta( $ID, '__wpdm_terms_page', true );
406 $terms_title = get_post_meta( $ID, '__wpdm_terms_title', true );
407 $terms_conditions = get_post_meta( $ID, '__wpdm_terms_conditions', true );
408 if ( $terms_page ) {
409 $terms_page = get_post( $terms_page );
410 $terms_title = $terms_page->post_title;
411 $terms_conditions = $terms_page->post_content;
412 }
413 $terms_title = $terms_title !== '' ? $terms_title : __( "Terms and Conditions", 'download-manager' );
414 $terms_check_label = get_post_meta( $ID, '__wpdm_terms_check_label', true );
415 $terms_check_label = $terms_check_label ? $terms_check_label : __( "I Agree With Terms and Conditions", 'download-manager' );
416
417 $data['terms_title'] = $terms_title;
418 $data['terms_check_label'] = $terms_check_label;
419 $data['terms_conditions'] = $terms_conditions;
420
421 if ( ! self::isLocked( $post_vars ) ) {
422 $post_vars['download_link_popup'] = $post_vars['download_link'] = "<a href='#unlock' class='wpdm-download-link wpdm-download-locked {$post_vars['btnclass']}' data-package='{$post_vars['ID']}'>{$post_vars['link_label']}</a>";
423 }
424
425 $post_vars['download_link_extended'] = "<div class='panel panel-default card card terms-panel' style='margin: 0'><div class='panel-heading card-header'>{$terms_title}</div><div class='panel-body card-body' style='max-height: 200px;overflow: auto'>{$terms_conditions}</div><div class='panel-footer card-footer'><label><input data-pid='{$post_vars['ID']}' class='wpdm-checkbox terms_checkbox terms_checkbox_{$post_vars['ID']}' type='checkbox' onclick='jQuery(\".download_footer_{$post_vars['ID']}\").slideToggle();'> {$terms_check_label}</label></div><div class='panel-footer card-footer download_footer_{$post_vars['ID']}' style='display:none;'>{$post_vars['download_link_extended']}</div></div><script>jQuery(function($){ $('#wpdm-filelist-{$post_vars['ID']} .btn.inddl, #xfilelist .btn.inddl').attr('disabled', 'disabled'); });</script>";
426
427 }
428
429 if ( ! isset( $post_vars['formatted'] ) ) {
430 $post_vars['formatted'] = 0;
431 }
432 ++ $post_vars['formatted'];
433
434 $post_vars['__template'] = $template;
435 $post_vars['__template_type'] = $template_type;
436 $post_vars = apply_filters( 'wpdm_after_prepare_package_data', $post_vars, $template_type );
437
438 $this->packageData = $post_vars;
439
440 foreach ( $post_vars as $key => $val ) {
441 try {
442 if(isset($this->{$key})) {
443 $this->{$key} = $val;
444 }
445 } catch ( \Exception $e ) {
446 }
447 }
448
449 return $this;
450 }
451
452 /**
453 * @usage Get all or any specific package info
454 *
455 * @param $ID
456 * @param null $meta
457 *
458 * @return mixed
459 */
460 public static function get( $ID, $meta = null ) {
461 $ID = (int) $ID;
462 if ( $ID == 0 ) {
463 return null;
464 }
465 if ( $meta != null ) {
466 return get_post_meta( $ID, "__wpdm_" . $meta, true );
467 }
468 $p = new PackageController();
469 $package = $p->prepare( $ID );
470
471 return $package->packageData;
472 }
473
474 /**
475 * @usage Verify single file download option
476 *
477 * @param null $ID
478 *
479 * @return mixed
480 */
481 public function isSingleFileDownloadAllowed( $ID = null ) {
482 global $post;
483 if ( ! $ID && $post->post_type == 'wpdmpro' ) {
484 $ID = $post->ID;
485 }
486 $global = get_option( '__wpdm_individual_file_download', 1 );
487 $package = get_post_meta( $ID, '__wpdm_individual_file_download', true );
488 $effective = $package == - 1 || $package == '' ? $global : $package;
489
490 return apply_filters( "wpdm_is_single_file_download_allowed", $effective, $ID );
491 }
492
493 /**
494 * @param $id
495 *
496 * @usage Returns the user roles who has access to specified package
497 * @return array|mixed
498 */
499 public function allowedRoles( $id ) {
500 $roles = get_post_meta( $id, '__wpdm_access', true );
501 $roles = maybe_unserialize( $roles );
502
503 $cats = get_the_terms( $id, 'wpdmcategory' );
504 if ( ! is_array( $roles ) ) {
505 $roles = array();
506 }
507 if ( is_array( $cats ) ) {
508 foreach ( $cats as $cat ) {
509 $croles = WPDM()->categories->getAllowedRoles( $cat->term_id );
510 $roles = array_merge( $roles, $croles );
511 }
512 }
513
514 $roles = array_unique( $roles );
515
516 $roles = apply_filters( "wpdm_allowed_roles", $roles, $id );
517 if ( ! is_array( $roles ) ) {
518 $roles = array();
519 }
520
521 return $roles;
522 }
523
524 /**
525 * @usage Check if a package is locked or public
526 *
527 * @param $id
528 *
529 * @return bool
530 */
531 public function isLocked( $package = null ) {
532 if ( ! $package ) {
533 $package = $this->ID;
534 }
535 if ( ! is_array( $package ) && (int) $package > 0 ) {
536 $id = $package;
537 $package = array();
538 $package['ID'] = $id;
539 $package['email_lock'] = get_post_meta( $id, '__wpdm_email_lock', true );
540 $package['password_lock'] = get_post_meta( $id, '__wpdm_password_lock', true );
541 $package['gplusone_lock'] = get_post_meta( $id, '__wpdm_gplusone_lock', true );
542 $package['tweet_lock'] = get_post_meta( $id, '__wpdm_tweet_lock', true );
543 $package['twitterfollow_lock'] = get_post_meta( $id, '__wpdm_twitterfollow_lock', true );
544 $package['facebooklike_lock'] = get_post_meta( $id, '__wpdm_facebooklike_lock', true );
545 $package['linkedin_lock'] = get_post_meta( $id, '__wpdm_linkedin_lock', true );
546 $package['captcha_lock'] = get_post_meta( $id, '__wpdm_captcha_lock', true );
547 } else {
548 $id = $package['ID'];
549 }
550 $lock = '';
551 $package = apply_filters( 'wpdm_custom_data', $package, $id );
552 if ( isset( $package['email_lock'] ) && (int) $package['email_lock'] == 1 ) {
553 $lock = 'locked';
554 }
555 if ( isset( $package['password_lock'] ) && (int) $package['password_lock'] == 1 ) {
556 $lock = 'locked';
557 }
558 if ( isset( $package['gplusone_lock'] ) && (int) $package['gplusone_lock'] == 1 ) {
559 $lock = 'locked';
560 }
561 if ( isset( $package['tweet_lock'] ) && (int) $package['tweet_lock'] == 1 ) {
562 $lock = 'locked';
563 }
564 if ( isset( $package['twitterfollow_lock'] ) && (int) $package['twitterfollow_lock'] == 1 ) {
565 $lock = 'locked';
566 }
567 if ( isset( $package['facebooklike_lock'] ) && (int) $package['facebooklike_lock'] == 1 ) {
568 $lock = 'locked';
569 }
570 if ( isset( $package['linkedin_lock'] ) && (int) $package['linkedin_lock'] == 1 ) {
571 $lock = 'locked';
572 }
573 if ( isset( $package['captcha_lock'] ) && (int) $package['captcha_lock'] == 1 ) {
574 $lock = 'locked';
575 }
576
577 if ( $lock !== 'locked' ) {
578 $lock = apply_filters( 'wpdm_check_lock', $lock, $id );
579 }
580
581 return ( $lock === 'locked' );
582 }
583
584 /**
585 * Check if a package with the given $ID is password protected
586 *
587 * @param $ID
588 *
589 * @return bool
590 */
591 function isPasswordProtected( $ID ) {
592 $locked = (int) get_post_meta( $ID, '__wpdm_password_lock', true );
593 $password = get_post_meta( $ID, '__wpdm_password', true );
594
595 return $locked && $password ? $password : false;
596 }
597
598 /**
599 * @usage Check if current user has access to package or category
600 *
601 * @param $id
602 * @param string $type
603 *
604 * @return bool
605 */
606 public function userCanAccess( $ID = null, $type = 'package' ) {
607 global $current_user;
608 $ID = $ID ? $ID : $this->ID;
609 if ( ! $ID ) {
610 return false;
611 }
612 if ( $type == 'package' ) {
613 $roles = $this->allowedRoles( $ID );
614 } else {
615 $roles = WPDM()->categories->getAllowedRoles( $ID );
616 }
617
618 if ( ! is_array( $roles ) ) {
619 $roles = array();
620 }
621 $matched = is_user_logged_in() ? array_intersect( $current_user->roles, $roles ) : array();
622
623 if ( $type === 'category' && count( $roles ) == 0 ) {
624 return true;
625 }
626 if ( in_array( 'guest', $roles ) ) {
627 return true;
628 }
629 if ( count( $matched ) > 0 ) {
630 return true;
631 }
632
633 return false;
634
635 }
636
637 /**
638 * @usage Check if current user has access to package or category based on roles
639 *
640 * @param $id
641 * @param string $type
642 *
643 * @return bool
644 */
645 public function userHasAccess( $user_id, $ID, $type = 'package' ) {
646
647 $user = get_user_by( 'ID', $user_id );
648
649 if ( $type == 'package' ) {
650 $roles = $this->allowedRoles( $ID );
651 } else {
652 $roles = WPDM()->categories->getAllowedRoles( $ID );
653 }
654
655 if ( ! is_array( $roles ) ) {
656 $roles = array();
657 }
658 $matched = is_user_logged_in() ? array_intersect( $user->roles, $roles ) : array();
659 if ( $type === 'category' && count( $roles ) == 0 ) {
660 return true;
661 }
662 if ( in_array( 'guest', $roles ) ) {
663 return true;
664 }
665 if ( count( $matched ) > 0 ) {
666 return true;
667 }
668
669 return false;
670
671 }
672
673 /**
674 * @usage Check user's download limit
675 *
676 * @param $ID
677 *
678 * @return bool
679 */
680 public static function userDownloadLimitExceeded( $ID ) {
681 global $current_user;
682
683 if ( is_user_logged_in() ) {
684 $index = $current_user->ID;
685 } else {
686 $index = __::get_client_ip();
687 }
688
689 $stock = (int) get_post_meta( $ID, '__wpdm_quota', true );
690 $download_count = (int) get_post_meta( $ID, '__wpdm_download_count', true );
691
692 $user_download_count = WPDM()->downloadHistory->userDownloadCount( $ID );
693
694 $download_limit_per_user = (int) get_post_meta( $ID, '__wpdm_download_limit_per_user', true );
695
696 if ( $download_limit_per_user > 0 && $user_download_count >= $download_limit_per_user ) {
697 return apply_filters( "wpdm_user_download_limit_exceeded", true, $ID );
698 }
699
700 $exceeded = false;
701
702 if ( $stock > 0 && $download_count >= $stock ) {
703 $exceeded = true;
704 };
705
706 $exceeded = apply_filters( "wpdm_user_download_limit_exceeded", $exceeded, $ID );
707
708 return $exceeded;
709 }
710
711 function userDownloadCount( $ID ) {
712 global $wpdb;
713 //$wpdb->
714 }
715
716 /**
717 * @usage Check if user is can download this package
718 *
719 * @param $ID
720 *
721 * @return bool
722 */
723 public function userCanDownload( $ID ) {
724 return $this->userCanAccess( $ID ) && ! $this->userDownloadLimitExceeded( $ID );
725 }
726
727 /**
728 * @usage Count files in a package
729 *
730 * @param $id
731 *
732 * @return int
733 */
734 public function fileCount( $ID ) {
735
736 $count = count( $this->getFiles( $ID, true ) );
737
738 return $count;
739
740 }
741
742 /**
743 * @param $ID
744 *
745 * @return bool
746 */
747 function hasAttachment($ID)
748 {
749 $files = maybe_unserialize( get_post_meta( $ID, '__wpdm_files', true ) );
750 if(!$files) return false;
751 return true;
752 }
753
754 /**
755 * @usage Get list of attached files & all files inside attached dir with a package
756 *
757 * @param $ID
758 *
759 * @return array|mixed
760 */
761 public function getFiles( $ID, $include_dir = false ) {
762 $files = maybe_unserialize( get_post_meta( $ID, '__wpdm_files', true ) );
763 if ( ! $files || ! is_array( $files ) ) {
764 $files = array();
765 }
766 foreach ( $files as &$file ) {
767 $file = rtrim( $file );
768 }
769
770 $files = apply_filters( "wpdm_get_files", $files, $ID );
771
772 return $files;
773 }
774
775 /**
776 * @usage Create zip from attached files
777 *
778 * @param $ID
779 *
780 * @return mixed|string|\WP_Error
781 */
782 public function zip( $ID ) {
783 $files = $this->getFiles( $ID );
784 $zipped = get_post_meta( $ID, "__wpdm_zipped_file", true );
785 if ( count( $files ) > 0 ) {
786 if ( $zipped == '' || ! file_exists( $zipped ) ) {
787 $zipped = UPLOAD_DIR . sanitize_file_name( get_the_title( $ID ) ) . '-' . $ID . '.zip';
788 $zipped = FileSystem::zipFiles( $files, $zipped );
789
790 return $zipped;
791 }
792 }
793
794 return new \WP_Error( 404, __( "No File Attached!", "download-manager" ) );
795 }
796
797 /**
798 * @usage Calculate package size
799 *
800 * @param $ID
801 * @param bool|false $recalculate
802 *
803 * @return bool|float|int|mixed|string
804 */
805 public function size( $ID, $recalculate = false ) {
806
807 if ( get_post_type( $ID ) != 'wpdmpro' ) {
808 return false;
809 }
810
811 $size = get_post_meta( $ID, '__wpdm_package_size', true );
812
813 if ( $size != "" && ! $recalculate ) {
814 return $size;
815 }
816
817 $files = $this->getFiles( $ID );
818
819 $size = 0;
820 if ( is_array( $files ) ) {
821 foreach ( $files as $f ) {
822 $f = trim( $f );
823 if ( __::is_url( $f ) ) {
824 continue;
825 }
826 if ( file_exists( $f ) ) {
827 $size += @filesize( $f );
828 } else {
829 $size += @filesize( UPLOAD_DIR . $f );
830 }
831 }
832 }
833
834 $size = apply_filters("wpdm_before_update_package_size", $size, $ID);
835
836 update_post_meta( $ID, '__wpdm_package_size_b', $size );
837 $size = $size / 1024;
838 if ( $size > 1024 ) {
839 $size = number_format( $size / 1024, 2 ) . ' MB';
840 } else {
841 $size = number_format( $size, 2 ) . ' KB';
842 }
843 update_post_meta( $ID, '__wpdm_package_size', $size );
844
845 return $size;
846 }
847
848 /**
849 * @usage Generate play button for link template
850 *
851 * @param $package
852 * @param bool $return
853 * @param $style
854 *
855 * @return mixed|string|void
856 */
857 public function audioPlayer( $package, $return = true, $style = 'primary btn-lg wpdm-btn-play-lg' ) {
858
859 $audiohtml = "";
860
861 if ( ! is_array( $package['files'] ) || count( $package['files'] ) == 0 ) {
862 return;
863 }
864 $audios = array();
865 $audio = $audx = null;
866 foreach ( $package['files'] as $index => $file ) {
867 $realpath = file_exists( $file ) ? $file : UPLOAD_DIR . $file;
868 $filetype = wp_check_filetype( $realpath );
869 $tmpvar = explode( '/', $filetype['type'] );
870 if ( $tmpvar[0] == 'audio' ) {
871 $audio = $file;
872 $audx = $index;
873 break;
874 }
875 }
876
877 if ( $audio != null ) {
878 $song = FileSystem::mediaURL( $package['ID'], $audx, basename( $audio ) ); //home_url("/?wpdmdl={$package['ID']}&ind=".$audx."&play=".basename($audio));
879 $audiohtml = "<button data-player='wpdm-audio-player' data-song='{$song}' class='btn btn-{$style} wpdm-btn-play'><i class='fa fa-play'></i></button>";
880 $audiohtml = apply_filters( "wpdm_audio_play_button", $audiohtml, $song, $package, 0 );
881 }
882
883 if ( $return ) {
884 return $audiohtml;
885 }
886
887 echo $audiohtml;
888
889 }
890
891 /**
892 * @param $ID
893 * @param $files
894 * @param int $width
895 *
896 * @return string
897 */
898 public static function videoPlayer( $ID, $files = null, $width = 800 ) {
899
900 if ( ! $files ) {
901 $files = WPDM()->package->getFiles( $ID );
902 }
903
904 $videos = array();
905 foreach ( $files as $index => $file ) {
906 $realpath = file_exists( $file ) ? $file : UPLOAD_DIR . $file;
907 $filetype = wp_check_filetype( $realpath );
908 $tmpvar = explode( '/', $filetype['type'] );
909 if ( $tmpvar[0] == 'video' ) {
910 $videos[] = $file;
911 $vidx[] = $index;
912 }
913
914 }
915
916 $videothumbs = "";
917 $mpvs = get_post_meta( $ID, '__wpdm_additional_previews', true );
918 $mmv = 0;
919
920 if ( is_array( $mpvs ) && count( $mpvs ) > 1 && count( $videos ) > 1 ) {
921
922 foreach ( $mpvs as $i => $mpv ) {
923 if ( $mmv < count( $videos ) ) {
924 //$url = self::expirableDownloadLink($ID, 3);
925 $ind = $vidx[ $i ]; //\WPDM_Crypt::Encrypt($videos[$mmv]);
926 //$video = $url . "&ind={$ind}&play=" . basename($videos[$mmv]);
927 $video = FileSystem::mediaURL( $ID, $ind, wpdm_basename( $videos[ $mmv ] ) );
928
929 $videothumbs .= "<a href='#' data-video='{$video}' class='__wpdm_playvideo'><img class='thumbnail' src='" . wpdm_dynamic_thumb( $mpv, array(
930 64,
931 64
932 ) ) . "'/></a>";
933 }
934 $mmv ++;
935 }
936 }
937
938 $player_html = '';
939 if ( count( $videos ) > 0 ) {
940 //$url = self::expirableDownloadLink($ID, 10);
941 $ind = $vidx[0]; //\WPDM_Crypt::Encrypt($videos[0]);
942 //$video = $url . "&ind={$ind}&play=" . basename($videos[0]);
943 $video = FileSystem::mediaURL( $ID, $ind, wpdm_basename( $videos[0] ) );
944
945 $player_html = "<video id='__wpdm_videoplayer' class='thumbnail' width=\"{$width}\" controls controlsList='nodownload'><source src=\"{$video}\" type=\"video/mp4\">Your browser does not support HTML5 video.</video><div class='videothumbs'>{$videothumbs}</div>";
946 //if(!WPDM()->package->userCanAccess($ID)) $player_html = \WPDM\__\Messages::Error(stripslashes(get_option('wpdm_permission_msg')), -1);
947 }
948
949 $player_html = apply_filters( "wpdm_video_player_html", $player_html, $ID, $file, $width );
950
951 return $player_html;
952 }
953
954 /**
955 * @param $ID
956 * @param $files
957 * @param int $width
958 * @param int $height
959 *
960 * @return mixed|string
961 */
962 public function productPreview( $ID, $files = null, $width = 800, $height = 600 ) {
963 if ( ! $files ) {
964 $files = WPDM()->package->getFiles( $ID );
965 }
966 $tfiles = $files;
967 $keys = array_keys( $files );
968 $ind = $keys[0];
969 $file = array_shift( $tfiles );
970 $realpath = file_exists( $file ) ? $file : UPLOAD_DIR . $file;
971 $filetype = wp_check_filetype( $realpath );
972 $type = explode( '/', $filetype['type'] );
973 $type = $type[1];
974 switch ( $type ) {
975 case 'mpeg':
976 case 'mp4':
977 return self::videoPlayer( $ID, $files, $width );
978 case 'png':
979 case 'jpg':
980 case 'jpeg':
981 return "<img src='" . FileSystem::imageThumbnail( $realpath, $width, $height ) . "' alt='" . esc_attr(get_the_title( $ID )) . "'/>";
982 case 'pdf':
983 $url = self::expirableDownloadLink( $ID, 1, 300 );
984 //$ind = \WPDM_Crypt::Encrypt($file);
985 $url .= "&ind={$ind}";
986
987 return FileSystem::docViewer( $url, $ID, 'pdf' );
988 default:
989 return '';
990 }
991 }
992
993 /**
994 * @usage Get All Custom Data of a Package
995 *
996 * @param $pid
997 *
998 * @return array
999 */
1000 public function metaData( $ID ) {
1001 global $wpdb;
1002
1003 $metaValidate = [
1004 '__wpdm_icon' => 'txt',
1005 '__wpdm_view_count' => 'int',
1006 '__wpdm_download_count' => 'int',
1007 '__wpdm_link_label' => 'txt',
1008 '__wpdm_version' => 'txt',
1009 '__wpdm_quota' => 'int',
1010 '__wpdm_access' => 'array',
1011 '__wpdm_package_size' => 'txt',
1012 '__wpdm_download_limit_per_user' => 'int',
1013 '__wpdm_terms_lock' => 'int',
1014 '__wpdm_publish_date' => 'txt',
1015 '__wpdm_expire_date' => 'txt'
1016 ];
1017 $metaKeys = array_keys( $metaValidate );
1018 $metaData = $wpdb->get_results( "select * from {$wpdb->prefix}postmeta where meta_key in ('" . implode( '\',\'', $metaKeys ) . "') and post_id = '{$ID}'" );
1019
1020 $data = [];
1021 if ( is_array( $metaData ) ) {
1022 foreach ( $metaData as $metaDataRow ) {
1023 $key = str_replace( "__wpdm_", "", $metaDataRow->meta_key );
1024 if ( $key === 'publish_date' ) {
1025 $key = 'avail_date';
1026 $metaDataRow->meta_value = wp_date( get_option( 'date_format' ) . " " . get_option( 'time_format' ), strtotime( $metaDataRow->meta_value ) );
1027 }
1028 if ( $key === 'expire_date' ) {
1029 $metaDataRow->meta_value = wp_date( get_option( 'date_format' ) . " " . get_option( 'time_format' ), strtotime( $metaDataRow->meta_value ) );
1030 }
1031 //if($metaValidate[$metaDataRow->meta_key] === 'array' && !is_array($metaDataRow->meta_value)) $metaDataRow->meta_value = unserialize($metaDataRow->meta_value);
1032 //else
1033 // $metaDataRow->meta_value = __::sanitize_var($metaDataRow->meta_value, $metaValidate[$metaDataRow->meta_key]);
1034 $data[ $key ] = wpdm_sanitize_var( maybe_unserialize( $metaDataRow->meta_value ), $metaValidate[ $metaDataRow->meta_key ] );
1035 }
1036 }
1037 unset( $metaData );
1038 $data = apply_filters( 'wpdm_custom_data', $data, $ID );
1039 if ( ! is_array( $data ) ) {
1040 $data = [];
1041 }
1042
1043 return $data;
1044 }
1045
1046 /**
1047 * @usage Generate download link of a package
1048 *
1049 * @param $package
1050 * @param int $embed
1051 * @param array $extras
1052 *
1053 * @return string
1054 */
1055 function prepareDownloadLink( &$package, $embed = 0, $extras = array() ) {
1056 global $wpdb, $current_user, $wpdm_download_icon, $wpdm_download_lock_icon, $btnclass;
1057 if ( is_array( $extras ) ) {
1058 extract( $extras );
1059 }
1060 $data = '';
1061
1062 $package['link_url'] = home_url( '/?download=1&' );
1063 $package['link_label'] = ! isset( $package['link_label'] ) || $package['link_label'] == '' ? __( "Download", "download-manager" ) : $package['link_label'];
1064
1065 //Change link label using a button image
1066 $template_type = isset( $template_type ) ? $template_type : 'link';
1067 $package['link_label'] = apply_filters( 'wpdm_button_image', $package['link_label'], $package, $template_type );
1068
1069
1070 $package['download_url'] = wpdm_download_url( $package );
1071 if ( wpdm_is_download_limit_exceed( $package['ID'] ) ) {
1072 $limit_msg = Messages::download_limit_exceeded( $package['ID'] );
1073 $package['download_url'] = '#';
1074 $package['link_label'] = $limit_msg;
1075 }
1076 if ( isset( $package['expire_date'] ) && $package['expire_date'] != "" && strtotime( $package['expire_date'] ) < time() ) {
1077 $package['download_url'] = '#';
1078 $package['link_label'] = apply_filters( "wpdm_download_expired_message", __( "Download was expired on", "download-manager" ) . " " . date_i18n( get_option( 'date_format' ) . " h:i A", strtotime( $package['expire_date'] ) ), $package );
1079 $package['download_link'] = $vars['download_link_extended'] = $vars['download_link_popup'] = "<a href='#'>{$package['link_label']}</a>";
1080
1081 return "<div class='alert alert-warning'><b>" . __( "Download:", "download-manager" ) . "</b><br/>{$package['link_label']}</div>";
1082 }
1083
1084 if ( isset( $package['publish_date'] ) && $package['publish_date'] != '' && strtotime( $package['publish_date'] ) > time() ) {
1085 $package['download_url'] = '#';
1086 $package['link_label'] = apply_filters( "wpdm_download_availability_message", __( "Download will be available from ", "download-manager" ) . " " . date_i18n( get_option( 'date_format' ) . " h:i A", strtotime( $package['publish_date'] ) ), $package );
1087 $package['download_link'] = $vars['download_link_extended'] = $vars['download_link_popup'] = "<a href='#'>{$package['link_label']}</a>";
1088
1089 return "<div class='alert alert-warning'><b>" . __( "Download:", "download-manager" ) . "</b><br/>{$package['link_label']}</div>";
1090 }
1091
1092 $link_label = isset( $package['link_label'] ) ? $package['link_label'] : __( "Download", "download-manager" );
1093
1094 $package['access'] = wpdm_allowed_roles( $package['ID'] );
1095
1096 if ( $package['download_url'] != '#' ) {
1097 $package['download_link'] = $vars['download_link_extended'] = $vars['download_link_popup'] = "<a class='wpdm-download-link {$btnclass}' rel='nofollow' href='#' onclick=\"location.href='{$package['download_url']}';return false;\"><i class='$wpdm_download_icon'></i>{$link_label}</a>";
1098 } else {
1099 $package['download_link'] = $vars['download_link_extended'] = $vars['download_link_popup'] = "<div class='alert alert-warning'><b>" . __( "Download:", "download-manager" ) . "</b><br/>{$link_label}</div>";
1100 }
1101 $caps = array_keys( $current_user->caps );
1102 $role = array_shift( $caps );
1103
1104 $matched = ( is_array( @maybe_unserialize( $package['access'] ) ) && is_user_logged_in() ) ? array_intersect( $current_user->roles, @maybe_unserialize( $package['access'] ) ) : array();
1105
1106 $skiplink = 0;
1107
1108 if ( is_user_logged_in() && count( $matched ) <= 0 && ! @in_array( 'guest', @maybe_unserialize( $package['access'] ) ) ) {
1109 $package['download_url'] = "#";
1110 $package['download_link'] = $vars['download_link_extended'] = $vars['download_link_popup'] = stripslashes( get_option( '__wpdm_permission_denied_msg' ) );
1111 $package = apply_filters( 'download_link', $package );
1112 if ( get_option( '_wpdm_hide_all', 0 ) == 1 ) {
1113 $package['download_link'] = $package['download_link_extended'] = 'blocked';
1114 }
1115
1116 return $package['download_link'];
1117 }
1118 if ( ! @in_array( 'guest', @maybe_unserialize( $package['access'] ) ) && ! is_user_logged_in() ) {
1119
1120 $loginform = wpdm_login_form( array( 'redirect' => get_permalink( $package['ID'] ) ) );
1121 if ( get_option( '_wpdm_hide_all', 0 ) == 1 ) {
1122 return 'loginform';
1123 }
1124 $package['download_url'] = $vars['download_link_extended'] = $vars['download_link_popup'] = home_url( '/wp-login.php?redirect_to=' . urlencode( __::valueof($_SERVER, 'REQUEST_URI', ['validate' => 'txt']) ) );
1125 $loginmsg = Messages::login_required( $package['ID'] );
1126 $package['download_link'] = stripcslashes( str_replace( array(
1127 "[loginform]",
1128 "[this_url]",
1129 "[package_url]"
1130 ), array( $loginform, __::valueof($_SERVER, 'REQUEST_URI', ['validate' => 'txt']), get_permalink( $package['ID'] ) ), $loginmsg ) );
1131
1132 return get_option( '__wpdm_login_form', 0 ) == 1 ? $loginform : $package['download_link'];
1133
1134 }
1135
1136 $package = apply_filters( 'download_link', $package );
1137
1138 $unqid = uniqid();
1139
1140 if ( ! isset( $package['quota'] ) || ( isset( $package['quota'] ) && $package['quota'] > 0 && $package['quota'] > $package['download_count'] ) || $package['quota'] == 0 ) {
1141 $lock = 0;
1142
1143 if ( isset( $package['password_lock'] ) && (int) $package['password_lock'] == 1 && $package['password'] != '' ) {
1144 $lock = 'locked';
1145 $data = PackageLocks::AskPassword( $package );
1146 }
1147
1148
1149 $sociallock = "";
1150
1151 if ( isset( $package['email_lock'] ) && (int) $package['email_lock'] == 1 ) {
1152 $data .= PackageLocks::AskEmail( $package );
1153 $lock = 'locked';
1154 }
1155
1156 if ( isset( $package['linkedin_lock'] ) && (int) $package['linkedin_lock'] == 1 ) {
1157 $lock = 'locked';
1158 $sociallock .= PackageLocks::LinkedInShare( $package );
1159
1160 }
1161
1162 if ( isset( $package['twitterfollow_lock'] ) && (int) $package['twitterfollow_lock'] == 1 ) {
1163 $lock = 'locked';
1164 $sociallock .= PackageLocks::TwitterFollow( $package );
1165
1166 }
1167
1168 if ( isset( $package['gplusone_lock'] ) && (int) $package['gplusone_lock'] == 1 ) {
1169 $lock = 'locked';
1170 $sociallock .= PackageLocks::GooglePlusOne( $package, true );
1171
1172 }
1173
1174 if ( isset( $package['tweet_lock'] ) && (int) $package['tweet_lock'] == 1 ) {
1175 $lock = 'locked';
1176 $sociallock .= PackageLocks::Tweet( $package );
1177
1178 }
1179
1180 if ( isset( $package['facebooklike_lock'] ) && (int) $package['facebooklike_lock'] == 1 ) {
1181 $lock = 'locked';
1182 $sociallock .= PackageLocks::FacebookLike( $package, true );
1183
1184 }
1185
1186
1187 if ( isset( $package['captcha_lock'] ) && (int) $package['captcha_lock'] == 1 ) {
1188 $lock = 'locked';
1189 $sociallock .= PackageLocks::reCaptchaLock( $package, true );
1190
1191 }
1192
1193 $extralocks = '';
1194 $extralocks = apply_filters( "wpdm_download_lock", $extralocks, $package );
1195
1196 if ( is_array( $extralocks ) && $extralocks['lock'] === 'locked' ) {
1197
1198 if ( isset( $extralocks['type'] ) && $extralocks['type'] == 'social' ) {
1199 $sociallock .= $extralocks['html'];
1200 } else {
1201 $data .= $extralocks['html'];
1202 }
1203
1204 $lock = 'locked';
1205 }
1206
1207 if ( $sociallock != "" ) {
1208 $data .= "<div class='panel panel-default card card-default'><div class='panel-heading card-header'>" . __( "Download", "download-manager" ) . "</div><div class='panel-body card-body wpdm-social-locks text-center'>{$sociallock}</div></div>";
1209 }
1210
1211 if ( $lock === 'locked' ) {
1212 $popstyle = isset( $popstyle ) && in_array( $popstyle, array(
1213 'popup',
1214 'pop-over'
1215 ) ) ? $popstyle : 'pop-over';
1216 if ( $embed == 1 ) {
1217 $adata = "</strong>{$data}";
1218 } else {
1219 //$dataattrs = $popstyle == 'pop-over'? 'data-title="'.__( "Download" , "download-manager" ).' ' . $package['title'] . '"' : 'data-toggle="modal" data-target="#pkg_' . $package['ID'] . "_" . $unqid . '"';
1220 $adata = '<a href="#pkg_' . $package['ID'] . "_" . $unqid . '" data-trigger="manual" data-package="' . $package['ID'] . '" class="wpdm-download-link wpdm-download-locked ' . $popstyle . ' ' . $btnclass . '"><i class=\'' . $wpdm_download_lock_icon . '\'></i>' . $package['link_label'] . '</a>';
1221
1222 // if ($popstyle == 'pop-over') {
1223 // if(!get_option('__wpdm_ajax_popup', false))
1224 // $adata .= '<div class="modal fade"><div class="row all-locks" id="pkg_' . $package['ID'] . "_" . $unqid . '">' . $data . '</div></div>';
1225 // }
1226 // else
1227 // $adata .= '<div class="modal fade" role="modal" id="pkg_' . $package['ID'] . "_" . $unqid . '"><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><strong style="margin:0px;font-size:12pt">' . __('Download') . '</strong></div><div class="modal-body">' . $data . '</div><div class="modal-footer text-right"><button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">Close</button></div></div></div></div>';
1228
1229 }
1230
1231 $data = $adata;
1232 }
1233 if ( $lock !== 'locked' ) {
1234
1235 $data = $package['download_link'];
1236
1237
1238 }
1239 } else {
1240 $data = Messages::download_limit_exceeded( $package['ID'] );
1241 }
1242
1243
1244 //return str_replace(array("\r","\n"),"",$data);
1245 return $data;
1246
1247 }
1248
1249 private static function activeLocks( $ID, $params = array( 'embed' => 0, 'popstyle' => 'pop-over' ) ) {
1250
1251 $embed = isset( $params['embed'] ) ? $params['embed'] : 0;
1252 $template_type = isset( $params['template_type'] ) ? $params['template_type'] : 'link';
1253 $popstyle = isset( $params['popstyle'] ) ? $params['popstyle'] : 'pop-over';
1254
1255 $package = array(
1256 'ID' => $ID,
1257 'password' => get_post_meta( $ID, '__wpdm_password', true ),
1258 'password_lock' => get_post_meta( $ID, '__wpdm_password_lock', true ),
1259 'email_lock' => get_post_meta( $ID, '__wpdm_email_lock', true ),
1260 'linkedin_lock' => get_post_meta( $ID, '__wpdm_linkedin_lock', true ),
1261 'twitterfollow_lock' => get_post_meta( $ID, '__wpdm_twitterfollow_lock', true ),
1262 'gplusone_lock' => get_post_meta( $ID, '__wpdm_gplusone_lock', true ),
1263 'tweet_lock' => get_post_meta( $ID, '__wpdm_tweet_lock', true ),
1264 'facebooklike_lock' => get_post_meta( $ID, '__wpdm_facebooklike_lock', true ),
1265 'captcha_lock' => get_post_meta( $ID, '__wpdm_captcha_lock', true ),
1266 );
1267
1268 $package = apply_filters( 'wpdm_before_apply_locks', $package );
1269 $lock = $data = "";
1270 $unqid = uniqid();
1271
1272 if ( isset( $package['password_lock'] ) && (int) $package['password_lock'] == 1 && $package['password'] != '' ) {
1273 $lock = 'locked';
1274 $data = PackageLocks::AskPassword( $package );
1275 }
1276
1277 $sociallock = "";
1278
1279
1280 $extralocks = '';
1281 $extralocks = apply_filters( "wpdm_download_lock", $extralocks, $package );
1282
1283 if ( is_array( $extralocks ) && $extralocks['lock'] === 'locked' ) {
1284
1285 if ( isset( $extralocks['type'] ) && $extralocks['type'] == 'social' ) {
1286 $sociallock .= $extralocks['html'];
1287 } else {
1288 $data .= $extralocks['html'];
1289 }
1290
1291 $lock = 'locked';
1292 }
1293
1294 if ( $sociallock !== "" ) {
1295 $socdesc = get_option( '_wpdm_social_lock_panel_desc', '' );
1296 $socdesc = $socdesc !== '' ? "<p>{$socdesc}</p>" : "";
1297 $data .= "<div class='panel panel-default card'><div class='panel-heading card-header'>" . get_option( '_wpdm_social_lock_panel_title', 'Like or Share to Download' ) . "</div><div class='panel-body card-body wpdm-social-locks text-center'>{$socdesc}{$sociallock}</div></div>";
1298 }
1299
1300
1301 if ( isset( $package['captcha_lock'] ) && (int) $package['captcha_lock'] == 1 ) {
1302 $lock = 'locked';
1303 $captcha = PackageLocks::reCaptchaLock( $package, true );
1304 $data .= $captcha; //"<div class='panel panel-default card'><div class='panel-heading card-header'>" . __("Verify CAPTCHA to Download", "download-manager") . "</div><div class='panel-body card-body wpdm-social-locks text-center'>{$captcha}</div></div>";
1305 }
1306
1307 if ( $lock === 'locked' ) {
1308 $popstyle = isset( $popstyle ) && in_array( $popstyle, array(
1309 'popup',
1310 'pop-over'
1311 ) ) ? $popstyle : 'pop-over';
1312 if ( $embed == 1 ) {
1313 $adata = "</strong>{$data}";
1314 } else {
1315 $link_label = get_post_meta( $ID, '__wpdm_link_label', true );
1316 $link_label = trim( $link_label ) ? $link_label : __( "Download", "download-manager" );
1317 $style = wpdm_download_button_style( ( $template_type === 'page' ), $ID );
1318 $style = isset( $params['btnclass'] ) && $params['btnclass'] !== '' ? $params['btnclass'] : $style;
1319 $adata = '<a href="#pkg_' . $ID . "_" . $unqid . '" data-package="' . $ID . '" data-trigger="manual" class="wpdm-download-link wpdm-download-locked ' . $style . '">' . $link_label . '</a>';
1320
1321 }
1322
1323 $data = $adata;
1324 }
1325
1326 return $data;
1327 }
1328
1329
1330 /**
1331 * @usage Generate download link of a package
1332 *
1333 * @param $package
1334 * @param int $embed
1335 * @param array $extras
1336 *
1337 * @return string
1338 */
1339 public function downloadLink( $ID, $embed = 0, $extras = array() ) {
1340 global $wpdb, $current_user, $wpdm_download_icon, $wpdm_download_lock_icon;
1341 if ( is_array( $extras ) ) {
1342 extract( $extras );
1343 }
1344
1345 // Performance: Prime post meta cache if not already loaded
1346 // This ensures all subsequent get_post_meta() calls hit the object cache
1347 $cached_meta = wp_cache_get( $ID, 'post_meta' );
1348 if ( false === $cached_meta ) {
1349 update_postmeta_cache( [ $ID ] );
1350 }
1351
1352 // Performance: Prime term meta cache for category access checks
1353 $terms = get_the_terms( $ID, 'wpdmcategory' );
1354 if ( is_array( $terms ) ) {
1355 $term_ids = wp_list_pluck( $terms, 'term_id' );
1356 update_termmeta_cache( $term_ids );
1357 }
1358
1359 if(!$this->hasAttachment($ID))
1360 return "<div class='alert alert-danger alert-sm'>".__('No file attached!', WPDM_TEXT_DOMAIN)."</div>";
1361
1362 $data = '';
1363
1364
1365 $template_type = isset( $extras['template_type'] ) ? $extras['template_type'] : 'page';
1366
1367 //$package = self::get($ID);
1368
1369 $link_label = get_post_meta( $ID, '__wpdm_link_label', true );
1370 $link_label = ( trim( $link_label ) === '' ) ? __( "Download", "download-manager" ) : $link_label;
1371
1372 $template_type = isset( $template_type ) ? $template_type : 'link';
1373 $link_label = apply_filters( "wpdm_link_label", $link_label, $ID, $template_type );
1374
1375 $loginmsg = Messages::login_required( $ID );
1376
1377 $download_url = $this->getDownloadURL( $ID );
1378
1379 $limit_over = 0;
1380 $alert_size = ( $template_type == 'link' ) ? 'alert-sm' : '';
1381
1382 if ( self::userDownloadLimitExceeded( $ID ) ) {
1383 $limit_msg = Messages::download_limit_exceeded( $ID );
1384 $download_url = '#';
1385 $link_label = $limit_msg;
1386 $limit_over = 1;
1387 }
1388
1389 $expired = get_post_meta( $ID, '__wpdm_expire_date', true );
1390 $publish = get_post_meta( $ID, '__wpdm_publish_date', true );
1391
1392 if ( $expired !== "" && strtotime( $expired ) < time() ) {
1393 $download_url = '#';
1394 $link_label = __( "Download was expired on", "download-manager" ) . " " . date_i18n( get_option( 'date_format' ) . " h:i A", strtotime( $expired ) );
1395
1396 return "<div class='alert alert-warning {$alert_size}' data-title='" . __( "DOWNLOAD ERROR:", "download-manager" ) . "'>{$link_label}</div>";
1397 }
1398
1399 if ( $publish !== "" && strtotime( $publish ) > time() ) {
1400 $download_url = '#';
1401 $link_label = __( "Download will be available from ", "download-manager" ) . " " . date_i18n( get_option( 'date_format' ) . " h:i A", strtotime( $publish ) );
1402
1403 return "<div class='alert alert-warning {$alert_size}' data-title='" . __( "DOWNLOAD ERROR:", "download-manager" ) . "'>{$link_label}</div>";
1404 }
1405
1406
1407 $style = wpdm_download_button_style( ( $template_type === 'page' ), $ID );
1408 $style = isset( $btnclass ) && $btnclass !== '' ? $btnclass : $style;
1409
1410 if ( $download_url != '#' ) {
1411 $download_link = $download_link_extended = $download_link_popup = (int) get_option( '__wpdm_mask_dlink', 1 ) === 1 ? "<a class='wpdm-download-link download-on-click {$style}' rel='nofollow' href='#' data-downloadurl=\"{$download_url}\">{$link_label}</a>" : "<a class='wpdm-download-link {$style}' rel='nofollow' href='{$download_url}'>{$link_label}</a>";
1412 } //$download_link = $download_link_extended = $download_link_popup = (int)get_option('__wpdm_mask_dlink', 1) === 1 ? "<a class='wpdm-download-link {$style}' rel='nofollow' href='#' onclick=\"location.href='{$download_url}';return false;\">{$link_label}</a>" : "<a class='wpdm-download-link {$style}' rel='nofollow' href='{$download_url}'>{$link_label}</a>";
1413 else {
1414 $download_link = "<div class='alert alert-warning {$alert_size}' data-title='" . __( "DOWNLOAD ERROR:", "download-manager" ) . "'>{$link_label}</div>";
1415 }
1416
1417
1418 $access = self::allowedRoles( $ID );
1419 if ( ! is_array( $access ) ) {
1420 $access = array();
1421 }
1422 $matched = ( is_array( $access ) && is_user_logged_in() ) ? array_intersect( $current_user->roles, $access ) : array();
1423 if ( ! $matched ) {
1424 $matched = [];
1425 }
1426
1427 $skiplink = 0;
1428
1429 //User does't have permission to download
1430 if ( is_user_logged_in() && count( $matched ) <= 0 && ! @in_array( 'guest', $access ) ) {
1431 $download_url = "#";
1432 $download_link = $download_link_extended = $download_link_popup = Messages::permission_denied( $ID );
1433 if ( get_option( '_wpdm_hide_all', 0 ) == 1 ) {
1434 $download_link = $download_link_extended = $download_link_popup = 'blocked';
1435 }
1436
1437 return $download_link;
1438 }
1439
1440 //Login is required to download
1441 if ( ! @in_array( 'guest', $access ) && ! is_user_logged_in() ) {
1442
1443 $loginform = WPDM()->user->login->form( array( 'redirect' => __::valueof($_SERVER, 'REQUEST_URI', ['validate' => 'txt']) ) );
1444 if ( get_option( '_wpdm_hide_all', 0 ) == 1 ) {
1445 $hide_all_message = get_option( '__wpdm_login_form', 0 ) == 1 ? $loginform : stripcslashes( str_replace( array(
1446 "[loginform]",
1447 "[this_url]",
1448 "[package_url]"
1449 ), array( $loginform, __::valueof($_SERVER, 'REQUEST_URI', ['validate' => 'txt']), get_permalink( $ID ) ), $loginmsg ) );
1450 if ( $template_type == 'link' ) {
1451 return "<a href='" . wpdm_login_url( __::valueof($_SERVER, 'REQUEST_URI', ['validate' => 'txt']) ) . "' class='btn btn-danger'>" . __( "Login", "download-manager" ) . "</a>";
1452 } else {
1453 return $hide_all_message;
1454 }
1455 }
1456 $download_url = wpdm_login_url( __::valueof($_SERVER, 'REQUEST_URI', ['validate' => 'txt']) );
1457 $download_link = $download_link_extended = $download_link_popup = stripcslashes( str_replace( array(
1458 "[loginform]",
1459 "[this_url]",
1460 "[package_url]"
1461 ), array( $loginform, __::valueof($_SERVER, 'REQUEST_URI', ['validate' => 'txt']), get_permalink( $ID ) ), $loginmsg ) );
1462
1463 return get_option( '__wpdm_login_form', 0 ) == 1 ? $loginform : $download_link;
1464
1465 }
1466
1467 //$package = apply_filters('wpdm_before_apply_locks', $package);
1468 //$package = apply_filters('wpdm_after_prepare_package_data', $package);
1469
1470 $unqid = uniqid();
1471 $stock_limit = (int) get_post_meta( $ID, '__wpdm_quota', true );
1472 $download_count = (int) get_post_meta( $ID, '__wpdm_download_count', true );
1473 if ( $stock_limit > $download_count || $stock_limit == 0 ) {
1474 $lock = 0;
1475
1476 $extras['embed'] = $embed;
1477 $data = self::activeLocks( $ID, $extras );
1478
1479 $terms_lock = (int) get_post_meta( $ID, '__wpdm_terms_lock', true );
1480 $terms_page = (int) get_post_meta( $ID, '__wpdm_terms_page', true );
1481 $terms_title = get_post_meta( $ID, '__wpdm_terms_title', true );
1482 $terms_conditions = get_post_meta( $ID, '__wpdm_terms_conditions', true );
1483 if ( $terms_page ) {
1484 $terms_page = get_post( $terms_page );
1485 $terms_title = $terms_page->post_title;
1486 $terms_conditions = $terms_page->post_content;
1487 }
1488 $terms_check_label = get_post_meta( $ID, '__wpdm_terms_check_label', true );
1489 if ( $terms_lock !== 0 && ( ! function_exists( 'wpdmpp_effective_price' ) || wpdmpp_effective_price( $ID ) == 0 ) ) {
1490 if ( ! self::isLocked( $ID ) && ! $embed ) {
1491 $data = "<a href='#unlock' class='wpdm-download-link wpdm-download-locked {$style}' data-package='{$ID}'>{$link_label}</a>";
1492 } else {
1493 $data = $data ? $data : $download_link;
1494 }
1495 if ( $embed == 1 ) {
1496 $data = "<div class='panel panel-default card terms-panel' style='margin: 0 0 10px 0'><div class='panel-heading card-header'>{$terms_title}</div><div class='panel-body card-body' style='max-height: 200px;overflow: auto'>{$terms_conditions}</div><div class='panel-footer card-footer'><label><input data-pid='{$ID}' class='wpdm-checkbox terms_checkbox terms_checkbox_{$ID}' type='checkbox'> {$terms_check_label}</label></div><div class='panel-footer card-footer bg-white download_footer_{$ID}' style='display:none;'>{$data}</div></div><script>jQuery(function($){ $('#wpdm-filelist-{$ID} .btn.inddl, #xfilelist .btn.inddl').attr('disabled', 'disabled'); });</script>";
1497 }
1498
1499 }
1500
1501 if ( $data != "" ) {
1502 $data = apply_filters( 'wpdm_download_link', $data, $extras + array( 'ID' => $ID, 'id' => $ID ) );
1503
1504 return $data;
1505 }
1506
1507
1508 $data = $download_link;
1509
1510
1511 } else {
1512 $data = "<button class='btn btn-danger btn-block' type='button' disabled='disabled' data-title='DOWNLOAD ERROR:'>" . __( "Limit Over!", "download-manager" ) . "</button>";
1513 }
1514 if ( $data == 'loginform' ) {
1515 return WPDM()->user->login->form();
1516 }
1517 $data = apply_filters( 'wpdm_download_link', $data, $extras + array( 'ID' => $ID, 'id' => $ID ) );
1518
1519 return $data;
1520
1521 }
1522
1523 /**
1524 * @usage Generate download url for public/open downloads, the url will not work for the packages with lock option
1525 *
1526 * @param $ID
1527 * @param $ext
1528 *
1529 * @return string
1530 */
1531 public function getDownloadURL( $ID, $ext = array() ) {
1532 if ( self::isLocked( $ID ) && ! Session::get( '__wpdm_unlocked_' . $ID ) ) {
1533 return '#locked';
1534 }
1535 if ( ! is_array( $ext ) ) {
1536 $ext = [];
1537 }
1538 $ext['wpdmdl'] = $ID;
1539 $ext['refresh'] = uniqid() . time();
1540 $permalink = get_permalink( $ID );
1541 $permalink = apply_filters( "wpdm_download_url_base", $permalink, $ID );
1542 $download_url = add_query_arg( $ext, $permalink );
1543 $flat = (int) get_option( '__wpdm_flat_download_url', 0 );
1544 $code = json_encode( $ext );
1545 $code = base64_encode( $code );
1546 $code = rtrim( $code, '=' );
1547 $filename = isset( $ext['filename'] ) ? $ext['filename'] : '';
1548 if ( isset( $ext['ind'] ) && $filename == '' ) {
1549 $files = $this->getFiles( $ID );
1550 $filename = wpdm_basename( $files[ $ext['ind'] ] );
1551 }
1552 if ( ! isset( $ext['ind'] ) && $filename == '' ) {
1553 $files = $this->getFiles( $ID );
1554 if ( count( $files ) > 1 ) {
1555 $filename = sanitize_file_name( get_the_title( $ID ) ) . ".zip";
1556 } else {
1557 $filename = array_shift( $files );
1558 $filename = wpdm_basename( $filename );
1559 }
1560
1561 }
1562 if ( $flat ) {
1563 $download_url = home_url( "/wpdmdl/{$ID}-{$code}/{$filename}" );
1564 }
1565
1566 return $download_url;
1567 }
1568
1569 /**
1570 * @param $ID
1571 *
1572 * @return false|string
1573 */
1574 public function getMasterDownloadURL( $ID ) {
1575 $package_url = get_permalink( $ID );
1576 $params['wpdmdl'] = $ID;
1577 $params['masterkey'] = get_post_meta( $ID, '__wpdm_masterkey', true );
1578 $download_url = add_query_arg( $params, $package_url );
1579
1580 return $download_url;
1581 }
1582
1583 /**
1584 * @param $ID
1585 * @param $Key
1586 *
1587 * @return bool
1588 */
1589 public function validateMasterKey( $ID, $Key ) {
1590 if ( $Key === '' || (int)get_option('__wpdm_mdl_off') === 1) {
1591 return false;
1592 }
1593 $masterKey = get_post_meta( $ID, '__wpdm_masterkey', true );
1594
1595 if ( $masterKey === '' ) {
1596 return false;
1597 }
1598 if ( $masterKey === $Key ) {
1599 return true;
1600 }
1601
1602 return false;
1603 }
1604
1605 /**
1606 * @param $ID
1607 * @param int $usageLimit
1608 * @param int $expirePeriod seconds
1609 *
1610 * @return string
1611 */
1612 function expirableDownloadLink( $ID, $usageLimit = 3, $expirePeriod = 604800, $sessionOnly = true ) {
1613 $key = wp_generate_password( 32, false );
1614 $exp = array( 'use' => $usageLimit, 'expire' => time() + $expirePeriod );
1615 if ( ! $sessionOnly ) {
1616 TempStorage::set( "__wpdmkey_{$key}_{$ID}", $exp, $expirePeriod, TempStorage::DURABLE_SCOPE );
1617 } else {
1618 Session::set( "__wpdmkey_{$key}_{$ID}", $exp, $expirePeriod );
1619 }
1620 //Session::set( '__wpdm_unlocked_'.$ID , 1 );
1621 //$download_url = $this->getDownloadURL($ID, "_wpdmkey={$key}");
1622 $permalink = get_permalink( $ID );
1623 $permalink = apply_filters( "wpdm_download_url_base", $permalink, $ID );
1624 $download_url = add_query_arg( array( "wpdmdl" => $ID, "_wpdmkey" => $key ), $permalink );
1625
1626 return $download_url;
1627 }
1628
1629 /**
1630 * @param $ID
1631 * @param int $usageLimit
1632 * @param int $expirePeriod seconds
1633 *
1634 * @return string
1635 */
1636 static function expirableDownloadPage( $ID, $usageLimit = 10, $expirePeriod = 604800, $sessionOnly = true ) {
1637 $key = wp_generate_password( 32, false );
1638 $exp = array( 'use' => $usageLimit, 'expire' => time() + $expirePeriod );
1639 if ( ! $sessionOnly ) {
1640 TempStorage::set( "__wpdmkey_{$key}_{$ID}", $exp, $expirePeriod, TempStorage::DURABLE_SCOPE );
1641 } else {
1642 Session::set( "__wpdmkey_{$key}_{$ID}", $exp, $expirePeriod );
1643 }
1644 $download_page_key = Crypt::encrypt( array( 'pid' => $ID, 'key' => $key ) );
1645 $download_page = home_url( "wpdm-download/{$download_page_key}" );
1646
1647 return $download_page;
1648 }
1649
1650
1651 /**
1652 * @usage Fetch link/page template and return generated html
1653 *
1654 * @param $template
1655 * @param $vars
1656 * @param string $type
1657 *
1658 * @return mixed|string
1659 */
1660 public function fetchTemplate( $template, $vars, $type = 'link' ) {
1661 if ( ! is_array( $vars ) && is_int( $vars ) && $vars > 0 ) {
1662 $vars = array( 'ID' => $vars );
1663 }
1664 if ( ! isset( $vars['ID'] ) || intval( $vars['ID'] ) < 1 ) {
1665 return '';
1666 }
1667
1668 $loginmsg = Messages::login_required( $vars['ID'] );
1669
1670 if ( ! is_user_logged_in() && count( self::allowedRoles( $vars['ID'] ) ) >= 0 && ! self::userCanAccess( $vars['ID'] ) ) {
1671 $loginform = wpdm_login_form( array( 'redirect' => get_permalink( $vars['ID'] ) ) );
1672 $hide_all_message = get_option( '__wpdm_login_form', 0 ) == 1 ? $loginform : stripcslashes( str_replace( array(
1673 "[loginform]",
1674 "[this_url]",
1675 "[package_url]"
1676 ), array( $loginform, __::valueof($_SERVER, 'REQUEST_URI', ['validate' => 'txt']), get_permalink( $vars['ID'] ) ), $loginmsg ) );
1677 if ( get_option( '_wpdm_hide_all', 0 ) == 1 ) {
1678 return $type == 'page' ? $hide_all_message : '';
1679 }
1680 }
1681
1682 if ( is_user_logged_in() && ! self::userCanAccess( $vars['ID'] ) && get_option( '_wpdm_hide_all', 0 ) == 1 ) {
1683 return $type != 'page' ? "" : get_option( '__wpdm_permission_denied_msg', __( "You are not allowed to download this item!", "download-manager" ) );
1684 }
1685
1686
1687 /*$default['link'] = 'link-template-default.php';
1688 $default['page'] = 'page-template-default.php';
1689
1690
1691 if ($template == '') {
1692 if (!isset($vars['page_template'])) $vars['page_template'] = 'page-template-1col.php';
1693 if (!isset($vars['template'])) $vars['template'] = 'link-template-calltoaction3.php';
1694 $template = $type == 'page' ? $vars['page_template'] : $vars['template'];
1695 }
1696
1697 if ($template == '')
1698 $template = $default[$type];
1699
1700 //$templates = maybe_unserialize(get_option("_fm_".$type."_templates", true));
1701 //if(isset($templates[$template]) && isset($templates[$template]['content'])) $template = $templates[$template]['content'];
1702 $template_content = WPDM()->packageTemplate->get($template, $type, true);
1703
1704 if ($template_content)
1705 $template = $template_content;
1706 else
1707 if (!strpos(strip_tags($template), "]")) {
1708 $template = wpdm_basename($template);
1709 $template = str_replace(".php", "", $template) . ".php";
1710 $themeltpldir = get_stylesheet_directory() . '/download-manager/' . $type . '-templates/';
1711 $pthemeltpldir = get_template_directory() . '/download-manager/' . $type . '-templates/';
1712 //if(!file_exists($ltpldir) || !file_exists($ltpldir.$template))
1713 $ltpldir = WPDM_TPL_DIR . $type . '-templates/';
1714
1715 $template_file = '';
1716 if (file_exists($themeltpldir . $template)) $template_file = ($themeltpldir . $template); // Apply if available in the child theme
1717 else if (file_exists($pthemeltpldir . $template)) $template_file = ($pthemeltpldir . $template); // Apply if available in the parent theme
1718 else if (file_exists($ltpldir . $template)) $template_file = ($ltpldir . $template);
1719 else if (file_exists($ltpldir . $type . "-template-" . $template)) $template_file = ($ltpldir . $type . "-template-" . $template);
1720 else $template_file = (wpdm_tpl_path($default[$type], $ltpldir));
1721
1722 if ($template_file !== '') {
1723 ob_start();
1724 $ID = $vars['ID'];
1725 global $wp_filter;
1726 $all_tc = $wp_filter['the_content'];
1727 unset($wp_filter['the_content']);
1728 remove_filter("the_content", "wpdm_downloadable");
1729 include $template_file;
1730 $template = ob_get_clean();
1731 $wp_filter['the_content'] = $all_tc;
1732 //add_filter("the_content", "wpdm_downloadable");
1733 if (!preg_match("/\[([^\]]+)\]/", $template, $found)) {
1734 return $template;
1735 }
1736 }
1737
1738 }*/
1739
1740 $ret = $this->prepare( $vars['ID'], $template, $type );
1741 if ( ! is_wp_error( $ret ) ) {
1742 $vars = $this->packageData;
1743 } else {
1744 return '';
1745 }
1746
1747 // Get template content
1748 $template = $this->getTemplateContent( $template, $vars['ID'], $type );
1749
1750 if ( isset( $vars['__loginform_only'] ) && $vars['__loginform_only'] != '' ) {
1751 return $vars['__loginform_only'];
1752 }
1753
1754 preg_match_all( "/\[cf ([^\]]+)\]/", $template, $cfmatches );
1755 preg_match_all( "/\[thumb_([0-9]+)x([0-9]+)\]/", $template, $matches );
1756 preg_match_all( "/\[thumb_url_([0-9]+)x([0-9]+)\]/", $template, $umatches );
1757 preg_match_all( "/\[thumb_gallery_([0-9]+)x([0-9]+)\]/", $template, $gmatches );
1758 preg_match_all( "/\[excerpt_([0-9]+)\]/", $template, $xmatches );
1759 preg_match_all( "/\[pdf_thumb_([0-9]+)x([0-9]+)\]/", $template, $pmatches );
1760 preg_match_all( "/\[txt=([^\]]+)\]/", $template, $txtmatches );
1761 preg_match_all( "/\[hide_empty:([^\]]+)\]/", $template, $hematches );
1762 preg_match_all( "/\[video_player_([0-9]+)\]/", $template, $vdmatches );
1763 preg_match_all( "/\[product_preview_([0-9]+)x([0-9]+)\]/", $template, $ppmatches );
1764 preg_match_all( "/\[file_list_extended_([0-9]+)x([0-9]+)x([0-9]+)\]/", $template, $flematches );
1765 preg_match_all( "/\[image_gallery_([0-9]+)x([0-9]+)x([0-9]+)\]/", $template, $igematches );
1766
1767
1768 //$thumb = wp_get_attachment_image_src(get_post_thumbnail_id($vars['ID']), 'full');
1769 //$vars['preview'] = $thumb['0'];
1770 //$vars['featured_image'] = ($vars['preview'] != '')?"<img src='{$vars['preview']}' alt='{$vars['title']}' />":"";
1771
1772 $tfiles = $vars['files'];
1773 $pdf = is_array( $tfiles ) ? array_shift( $tfiles ) : "";
1774 $ext = FileSystem::fileExt( $pdf );
1775
1776 // [video_player_...]
1777 foreach ( $vdmatches[0] as $nd => $scode ) {
1778 $scode = str_replace( array( '[', ']' ), '', $scode );
1779 $vars[ $scode ] = self::videoPlayer( $vars['ID'], $vars['files'], $vdmatches[1][ $nd ] );
1780 }
1781
1782 //Replace all file list extended tags
1783 foreach ( $flematches[0] as $nd => $scode ) {
1784 $scode = str_replace( array( "[", "]" ), "", $scode );
1785 $vars[ $scode ] = FileList::Box( $vars, $flematches[1][ $nd ], $flematches[2][ $nd ], $flematches[3][ $nd ] );
1786 }
1787
1788 //Replace all image gallery tags
1789 foreach ( $igematches[0] as $nd => $scode ) {
1790 $scode = str_replace( array( "[", "]" ), "", $scode );
1791 $vars[ $scode ] = FileList::imageGallery( $vars, $igematches[1][ $nd ], $igematches[2][ $nd ], $igematches[3][ $nd ] );
1792 }
1793
1794
1795 //Replace all txt variables
1796 foreach ( $txtmatches[0] as $nd => $scode ) {
1797 $scode = str_replace( array( '[', ']' ), '', $scode );
1798 $vars[ $scode ] = __( $txtmatches[1][ $nd ], "download-manager" );
1799 }
1800
1801 // Parse [pdf_thumb] tag in link/page template
1802 if ( strpos( $template, 'pdf_thumb' ) ) {
1803 if ( $ext == 'pdf' ) {
1804 $pdf_preview = FileSystem::pdfThumbnail( $pdf, $vars['ID'] );
1805 $vars['pdf_thumb'] = "<img alt='".esc_attr($vars['title'])."' src='" . $pdf_preview . "' />";
1806 $vars['pdf_thumb_url'] = $pdf_preview;
1807 $vars['pdf_name'] = str_replace( [ "pdf", "PDF" ], "", wp_basename( $pdf ) );
1808 } else {
1809 $vars['pdf_thumb'] = $vars['preview'] != '' ? "<img alt='".esc_attr($vars['title'])."' src='{$vars['preview']}' />" : "";
1810 }
1811 }
1812
1813 // Parse [pdf_thumb_WxH] tag in link/page template
1814 foreach ( $pmatches[0] as $nd => $scode ) {
1815 $imsrc = wpdm_dynamic_thumb( FileSystem::pdfThumbnail( $pdf, $vars['ID'] ), array(
1816 $pmatches[1][ $nd ],
1817 $pmatches[2][ $nd ]
1818 ) );
1819 $scode = str_replace( array( "[", "]" ), "", $scode );
1820 $vars[ $scode ] = $imsrc != '' ? "<img src='" . $imsrc . "' alt='".esc_attr($vars['title'])."' />" : '';
1821 }
1822
1823 // Parse [file_type] tag in link/page template
1824 if ( strpos( $template, 'file_type' ) ) {
1825 $vars['file_types'] = self::fileTypes( $vars['ID'], false );
1826 if ( is_array( $vars['file_types'] ) ) {
1827 $vars['file_types'] = implode( ", ", $vars['file_types'] );
1828 }
1829 $vars['file_type_icons'] = self::fileTypes( $vars['ID'] );
1830 }
1831
1832 $crop = get_option( '__wpdm_crop_thumbs', true );
1833
1834 // [thumb_WxH]
1835 foreach ( $matches[0] as $nd => $scode ) {
1836 $imsrc = wpdm_dynamic_thumb( $vars['preview'], array(
1837 $matches[1][ $nd ],
1838 $matches[2][ $nd ]
1839 ), $crop );
1840 $scode = str_replace( array( "[", "]" ), "", $scode );
1841 $vars[ $scode ] = $vars['preview'] != '' ? "<img class='wpdm-thumb wpdm-thumb-{$matches[1][$nd]}x{$matches[2][$nd]} wpdm-thumb-{$vars['ID']}' src='" . $imsrc . "' alt='".esc_attr($vars['title'])."' />" : '';
1842 }
1843
1844 // [thumb_url...]
1845 foreach ( $umatches[0] as $nd => $scode ) {
1846 $scode = str_replace( array( "[", "]" ), "", $scode );
1847 $vars[ $scode ] = $vars['preview'] != '' ? wpdm_dynamic_thumb( $vars['preview'], array(
1848 $umatches[1][ $nd ],
1849 $umatches[2][ $nd ]
1850 ), $crop ) : '';
1851 }
1852
1853 // [thumb_gallery...]
1854 foreach ( $gmatches[0] as $nd => $scode ) {
1855 $scode = str_replace( array( "[", "]" ), "", $scode );
1856 $vars[ $scode ] = $this->additionalPreviewImages( $vars, $gmatches[1][ $nd ], $gmatches[2][ $nd ] );
1857 }
1858
1859 // [product_preview...]
1860 foreach ( $ppmatches[0] as $nd => $scode ) {
1861 $scode = str_replace( array( "[", "]" ), "", $scode );
1862 $vars[ $scode ] = self::productPreview( $vars['ID'], $vars['files'], $ppmatches[1][ $nd ], $ppmatches[2][ $nd ] );
1863 }
1864
1865 // [excerpt_...]
1866 foreach ( $xmatches[0] as $nd => $scode ) {
1867 $ss = substr( strip_tags( $vars['description'] ), 0, intval( $xmatches[1][ $nd ] ) );
1868 $tmp = explode( " ", substr( strip_tags( $vars['description'] ), intval( $xmatches[1][ $nd ] ) ) );
1869 $bw = array_shift( $tmp );
1870 $ss .= $bw;
1871 $scode = str_replace( array( "[", "]" ), "", $scode );
1872 $vars[ $scode ] = $ss . '...';
1873 }
1874
1875 if ( $type == 'page' && ( strpos( $template, '[similar_downloads]' ) || strpos( $vars['description'], '[similar_downloads]' ) ) ) {
1876 $vars['similar_downloads'] = $this->similarPackages( $vars, 6 );
1877 }
1878
1879 if ( strpos( $template, 'doc_preview' ) ) {
1880 $vars['doc_preview'] = self::docPreview( $vars );
1881 }
1882
1883 if ( substr_count( $template, 'video_preview_modal' ) ) {
1884 $vars['video_preview_modal'] = self::videoPreviewModal( $vars, $type );
1885 }
1886
1887 // [changelog] – must be resolved before the [hide_empty:changelog] pass below
1888 if ( strpos( $template, '[changelog]' ) !== false ) {
1889 $vars['changelog'] = $this->changelog( $vars['ID'] );
1890 }
1891
1892
1893 $vars['fav_button'] = self::favBtn( $vars['ID'] );
1894 $vars['fav_button_sm'] = self::favBtn( $vars['ID'], array(
1895 'size' => 'btn-sm',
1896 'a2f_label' => "<i class='fa fa-heart'></i> &nbsp; " . __( "Add to favourite", "download-manager" ),
1897 'rff_label' => "<i class='fa fa-heart'></i> &nbsp; " . __( "Remove from favourite", "download-manager" )
1898 ) );
1899 $vars['fav_button_ico_sm'] = self::favBtn( $vars['ID'], array(
1900 'size' => 'btn-sm',
1901 'a2f_label' => "<i class='far fa-heart'></i>",
1902 'rff_label' => "<i class='fas fa-heart'></i>"
1903 ) );
1904 $vars['fav_button_ico'] = self::favBtn( $vars['ID'], array(
1905 'size' => '',
1906 'a2f_label' => "<i class='fa fa-heart'></i>",
1907 'rff_label' => "<i class='fa fa-heart'></i>"
1908 ) );
1909
1910
1911 // If need to re-process any data before fetch template
1912 $vars['__template_type'] = $type;
1913 $vars = apply_filters( "wdm_before_fetch_template", $vars, $template, $type );
1914
1915 foreach ( $hematches[0] as $index => $hide_empty ) {
1916 $hide_empty = str_replace( array( '[', ']' ), '', $hide_empty );
1917 if ( ! isset( $vars[ $hematches[1][ $index ] ] ) || ( $vars[ $hematches[1][ $index ] ] == '' || $vars[ $hematches[1][ $index ] ] == '0' ) ) {
1918 $vars[ $hide_empty ] = 'wpdm_hide wpdm_remove_empty';
1919 } else {
1920 $vars[ $hide_empty ] = '';
1921 }
1922 }
1923
1924
1925 $keys = array();
1926 $values = array();
1927
1928 foreach ( $vars as $key => $value ) {
1929 if ( ! is_array( $value ) && ! is_object( $value ) ) {
1930 $keys[] = "[$key]";
1931 $values[] = $value;
1932 }
1933 }
1934
1935
1936 $loginform = wpdm_login_form( array( 'redirect' => get_permalink( $vars['ID'] ) ) );
1937 $hide_all_message = get_option( '__wpdm_login_form', 0 ) == 1 ? $loginform : stripcslashes( str_replace( array(
1938 "[loginform]",
1939 "[this_url]",
1940 "[package_url]"
1941 ), array( $loginform, __::valueof($_SERVER, 'REQUEST_URI', ['validate' => 'txt']), get_permalink( $vars['ID'] ) ), $loginmsg ) );
1942
1943 if ( $vars['download_link'] == 'blocked' && $type == 'link' ) {
1944 return "";
1945 }
1946 if ( $vars['download_link'] == 'blocked' && $type == 'page' ) {
1947 return get_option( '__wpdm_permission_denied_msg' );
1948 }
1949 if ( $vars['download_link'] == 'loginform' && $type == 'link' ) {
1950 return "";
1951 }
1952 if ( $vars['download_link'] == 'loginform' && $type == 'page' ) {
1953 return $hide_all_message;
1954 }
1955
1956
1957 $template = str_replace( $keys, $values, @stripcslashes( $template ) );
1958
1959 $template = apply_filters( "wpdm_after_fetch_template", $template, $vars );
1960
1961 //wp_reset_query();
1962 //wp_reset_postdata();
1963 return $template;
1964 }
1965
1966 /*public static function parseTemplate($template, $post, $type = 'link')
1967 {
1968
1969 if (!strpos(strip_tags($template), "]")) {
1970
1971 $ltpldir = get_stylesheet_directory() . '/download-manager/' . $type . '-templates/';
1972 if (!file_exists($ltpldir) || !file_exists($ltpldir . $template))
1973 $ltpldir = WPDM_BASE_DIR . '/tpls/' . $type . '-templates/';
1974 if (file_exists(TEMPLATEPATH . '/' . $template)) $template = file_get_contents(TEMPLATEPATH . '/' . $template);
1975 else if (file_exists($ltpldir . $template)) $template = file_get_contents($ltpldir . $template);
1976 else if (file_exists($ltpldir . $template . '.php')) $template = file_get_contents($ltpldir . $template . '.php');
1977 else if (file_exists($ltpldir . $type . "-template-" . $template . '.php')) $template = file_get_contents($ltpldir . $type . "-template-" . $template . '.php');
1978 }
1979
1980 preg_match_all("/\[([^\]]+)\]/", $template, $matched);
1981 $post = (array)$post;
1982 $post['title'] = $post['post_title'];
1983 foreach ($matched[1] as $id => $key) {
1984 switch ($key) {
1985 case 'page_link':
1986 $post[$key] = "<a href='" . get_permalink($post['ID']) . "'>{$post['post_title']}</a>";
1987 break;
1988 case 'page_url':
1989 $post[$key] = get_permalink($post['ID']);
1990 break;
1991 case 'file_size':
1992 $post[$key] = get_post_meta($post['ID'], '__wpdm_package_size', true);
1993 break;
1994 default:
1995 $post[$key] = get_post_meta($post['ID'], '__wpdm_' . $key, true);
1996 break;
1997 }
1998 }
1999 $post = apply_filters("wdm_before_fetch_template", $post, $template, $type);
2000 $vars = array_keys($post);
2001 $vals = array_values($post);
2002 foreach ($vars as &$var) {
2003 $var = "[$var]";
2004 }
2005 $template = str_replace($vars, $vals, $template);
2006 $template = apply_filters("wpdm_after_fetch_template", $template, $vars);
2007 wp_reset_query();
2008 return $template;
2009 }*/
2010
2011 /**
2012 * @usage Find attached files types with a package
2013 *
2014 * @param $ID
2015 * @param bool|true $img
2016 *
2017 * @return array|string
2018 */
2019 public static function fileTypes( $ID, $img = true, $size = 16 ) {
2020 $files = maybe_unserialize( get_post_meta( $ID, '__wpdm_files', true ) );
2021 $ext = array();
2022 if ( is_array( $files ) ) {
2023 foreach ( $files as $f ) {
2024 $f = trim( $f );
2025 $ext[] = FileSystem::fileExt( $f );
2026 }
2027 }
2028
2029 $ext = array_unique( $ext );
2030 $exico = '';
2031 foreach ( $ext as $exi ) {
2032 $exico .= "<img alt='{$exi}' title='{$exi}' class='ttip' style='width:{$size}px;height:{$size}px;' src='" . FileSystem::fileTypeIcon( $exi ) . "' /> ";
2033 }
2034 if ( $img ) {
2035 return $exico;
2036 }
2037
2038 return $ext;
2039 }
2040
2041
2042 /**
2043 * @param $package
2044 *
2045 * @return string
2046 * @usage Generate Google Doc Preview
2047 */
2048 public function docPreview( $package ) {
2049
2050 //$files = $package['files'];
2051 $files = $this->getFiles( $package['ID'] );
2052 if ( ! is_array( $files ) ) {
2053 return "";
2054 }
2055 $ind = - 1;
2056 $fext = '';
2057 foreach ( $files as $i => $sfile ) {
2058 $ifile = $sfile;
2059 $sfile = explode( ".", $sfile );
2060 $fext = end( $sfile );
2061 if ( in_array( end( $sfile ), array( 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx' ) ) ) {
2062 $ind = $i;
2063 break;
2064 }
2065 }
2066
2067 if ( $ind == - 1 ) {
2068 return "";
2069 }
2070 $ext = count( $files ) > 1 ? 'ind=' . $ind : '';
2071 $params = array( 'ind' => $ind, 'filename' => $files[ $ind ] );
2072 $url = $this->getDownloadURL( $package['ID'], $params );
2073 $url .= "&open=1";
2074 if ( strpos( $ifile, "://" ) ) {
2075 $url = $ifile;
2076 }
2077 $doc_preview_html = FileSystem::docViewer( $url, $package['ID'], $fext );
2078 $doc_preview_html = apply_filters( 'wpdm_doc_preview', $doc_preview_html, $package, $url, $fext );
2079
2080 return $doc_preview_html;
2081 }
2082
2083 /**
2084 * Get additional preview images
2085 *
2086 * @param $file
2087 * @param $w
2088 * @param $h
2089 *
2090 * @return string
2091 */
2092 function additionalPreviewImages( $file, $w, $h ) {
2093
2094 $file['additional_previews'] = maybe_unserialize( get_post_meta( $file['ID'], '__wpdm_additional_previews', true ) );
2095 $k = 0;
2096 $img = '';
2097 $id = uniqid();
2098 if ( $file['additional_previews'] ) {
2099 foreach ( $file['additional_previews'] as $p ) {
2100 ++ $k;
2101 if ( is_numeric( $p ) ) {
2102 $img .= "<a href='" . wp_get_attachment_url( $p ) . "' id='more_previews_a_{$k}' class='more_previews_a imgpreview wpdm-lightbox' data-lightbox-gallery='gallery_{$id}' rel='previews'><img id='more_previews_{$k}' class='more_previews img-rounded' src='" . wpdm_dynamic_thumb( get_attached_file( $p ), array(
2103 $w,
2104 $h
2105 ) ) . "'/></a>";
2106 } else {
2107 $img .= "<a href='{$p}' id='more_previews_a_{$k}' class='more_previews_a imgpreview wpdm-lightbox' data-lightbox-gallery='gallery_{$id}' rel='previews' ><img id='more_previews_{$k}' class='more_previews img-rounded' src='" . wpdm_dynamic_thumb( $p, array(
2108 $w,
2109 $h
2110 ) ) . "'/></a>";
2111 }
2112 }
2113 }
2114 $js = ""; // "<script>jQuery(function($){ $('a.more_previews_a').nivoLightbox(); });</script>";
2115
2116 return $img . $js;
2117 }
2118
2119 /**
2120 * @usage Generates view preview modal link of the given package
2121 *
2122 * @param $package
2123 * @param int $embed
2124 * @param array $extras
2125 *
2126 * @return string
2127 */
2128 public function videoPreviewModal( $package, $template_type = 'link' ) {
2129 if ( is_int( $package ) ) {
2130 $package = get_post( $package, ARRAY_A );
2131 }
2132 $link_label = wpdm_valueof( $package, 'link_label' );
2133 $link_label = $link_label ? $link_label : $this->linkLabel( $package['ID'] );
2134 $style = wpdm_download_button_style( $template_type === 'page', $package['ID'] );
2135 $files = isset( $package['files'] ) ? $package['files'] : $this->getFiles( $package['ID'] );
2136 $video = "";
2137 foreach ( $files as $file ) {
2138 if ( substr_count( $file, 'youtu.be' ) || substr_count( $file, 'youtube.com' ) || substr_count( $file, 'vimeo.com' ) ) {
2139 $video = $file;
2140 }
2141 }
2142 $link = "<a class='wpdm-lightbox {$style}' href='{$video}'>{$link_label}</a>";
2143
2144 return $link;
2145
2146 }
2147
2148 /**
2149 * Get package link label
2150 *
2151 * @param $ID
2152 *
2153 * @return mixed|string|void
2154 */
2155 public function linkLabel( $ID ) {
2156 $link_label = get_post_meta( $ID, '__wpdm_link_label', true );
2157 $link_label = esc_attr( $link_label );
2158 $link_label = $link_label ? $link_label : __( "Download", "download-manager" );
2159
2160 return $link_label;
2161 }
2162
2163 /**
2164 * @usage Create New Package
2165 *
2166 * @param $data
2167 *
2168 * @return mixed
2169 */
2170 public static function create( $package_data ) {
2171
2172 if ( isset( $package_data['post_type'] ) ) {
2173 unset( $package_data['post_type'] );
2174 }
2175
2176 $package_data_core = array(
2177 'post_title' => '',
2178 'post_content' => '',
2179 'post_excerpt' => '',
2180 'post_status' => 'publish',
2181 'post_type' => 'wpdmpro',
2182 'post_author' => get_current_user_id(),
2183 'ping_status' => get_option( 'default_ping_status' ),
2184 'post_parent' => 0,
2185 'menu_order' => 0,
2186 'to_ping' => '',
2187 'pinged' => '',
2188 'post_password' => '',
2189 'guid' => '',
2190 'post_content_filtered' => '',
2191 'import_id' => 0
2192 );
2193
2194 $package_data_meta = array(
2195 'files' => array(),
2196 'fileinfo' => array(),
2197 'package_dir' => '',
2198 'link_label' => __( "Download", "download-manager" ),
2199 'download_count' => 0,
2200 'view_count' => 0,
2201 'version' => '1.0.0',
2202 'stock' => 0,
2203 'package_size' => 0,
2204 'package_size_b' => 0,
2205 'access' => '',
2206 'individual_file_download' => - 1,
2207 'cache_zip' => - 1,
2208 'template' => 'link-template-panel.php',
2209 'page_template' => 'page-template-1col-flat.php',
2210 'password_lock' => '0',
2211 'facebook_lock' => '0',
2212 'gplusone_lock' => '0',
2213 'linkedin_lock' => '0',
2214 'tweet_lock' => '0',
2215 'email_lock' => '0',
2216 'icon' => '',
2217 'import_id' => 0
2218 );
2219
2220 foreach ( $package_data_core as $key => &$value ) {
2221 $value = isset( $package_data[ $key ] ) ? $package_data[ $key ] : $package_data_core[ $key ];
2222 }
2223
2224 if ( ! isset( $package_data['ID'] ) ) {
2225 $post_id = wp_insert_post( $package_data_core );
2226 } else {
2227 $post_id = $package_data['ID'];
2228 $package_data_core['ID'] = $post_id;
2229 wp_update_post( $package_data_core );
2230 }
2231
2232 foreach ( $package_data_meta as $key => $value ) {
2233 $value = isset( $package_data[ $key ] ) ? $package_data[ $key ] : $package_data_meta[ $key ];
2234 update_post_meta( $post_id, '__wpdm_' . $key, $value );
2235 }
2236
2237 if ( isset( $package_data['cats'] ) ) {
2238 wp_set_post_terms( $post_id, $package_data['cats'], 'wpdmcategory' );
2239 }
2240
2241 if ( isset( $package_data['featured_image'] ) ) {
2242
2243 $wp_filetype = wp_check_filetype( wp_basename( $package_data['featured_image'] ), null );
2244
2245 if ( __::is_url( $package_data['featured_image'] ) ) {
2246 $upload_dir = wp_upload_dir();
2247 $file_path = $upload_dir['path'] . '/' . sanitize_file_name( $package_data['post_title'] ) . '.' . $wp_filetype['ext'];
2248 //$data = remote_get($package_data['featured_image']);
2249 //$ret = copy($package_data['featured_image'], $file_path);
2250 //if(!$ret) wpdmdd($package_data['featured_image']);
2251 file_put_contents( $file_path, wpdm_remote_get( $package_data['featured_image'] ) );
2252 $package_data['featured_image'] = $file_path;
2253 }
2254
2255 $mime_type = '';
2256
2257 if ( isset( $wp_filetype['type'] ) && $wp_filetype['type'] ) {
2258 $mime_type = $wp_filetype['type'];
2259 }
2260 unset( $wp_filetype );
2261 $attachment = array(
2262 'post_mime_type' => $mime_type,
2263 'post_parent' => $post_id,
2264 'post_title' => wp_basename( $package_data['featured_image'] ),
2265 'post_status' => 'inherit'
2266 );
2267 $attachment_id = wp_insert_attachment( $attachment, $package_data['featured_image'], $post_id );
2268 unset( $attachment );
2269
2270 if ( ! is_wp_error( $attachment_id ) ) {
2271 $attachment_data = wp_generate_attachment_metadata( $attachment_id, $package_data['featured_image'] );
2272 wp_update_attachment_metadata( $attachment_id, $attachment_data );
2273 unset( $attachment_data );
2274 set_post_thumbnail( $post_id, $attachment_id );
2275 }
2276 }
2277
2278 return $post_id;
2279 }
2280
2281 /**
2282 * @param $id
2283 * @param array $atfb
2284 *
2285 * @return string
2286 */
2287 public static function favBtn( $id, $atfb = array(), $count = true ) {
2288 if ( empty( $atfb ) ) {
2289 $atfb = array(
2290 'size' => '',
2291 'a2f_label' => "<i class='fa fa-heart'></i> &nbsp;" . __( "Add to favourite", "download-manager" ),
2292 'rff_label' => "<i class='fa fa-heart'></i> &nbsp; " . __( "Remove from favourite", "download-manager" )
2293 );
2294 }
2295 $atfb = apply_filters( "wpdm_fav_btn", $atfb, $id );
2296 $myfavs = maybe_unserialize( get_user_meta( get_current_user_id(), '__wpdm_favs', true ) );
2297 $ufavs = maybe_unserialize( get_post_meta( $id, '__wpdm_favs', true ) );
2298 $pfc = is_array( $ufavs ) ? count( $ufavs ) : 0;
2299 $btnclass = is_array( $myfavs ) && in_array( $id, $myfavs ) ? 'btn-danger' : 'btn-secondary';
2300 $label = is_array( $myfavs ) && in_array( $id, $myfavs ) ? $atfb['rff_label'] : $atfb['a2f_label'];
2301 extract( $atfb );
2302 if ( $count ) {
2303 return "<div class='btn-group'><button type='button' data-alabel=\"{$atfb['a2f_label']}\" data-rlabel=\"{$atfb['rff_label']}\" data-package='{$id}' class='btn btn-wpdm-a2f {$btnclass} {$size} btn-simple'>{$label}</button><button class='btn btn-secondary btn-simple {$size}' disabled='disabled'>{$pfc}</button></div>";
2304 } else {
2305 return "<button type='button' data-alabel=\"{$atfb['a2f_label']}\" data-rlabel=\"{$atfb['rff_label']}\" data-package='{$id}' class='btn btn-wpdm-a2f {$btnclass} {$size} btn-simple'>{$label}</button>";
2306 }
2307
2308 }
2309
2310 /**
2311 * Shows favourite count
2312 *
2313 * @param $id
2314 *
2315 * @return int
2316 */
2317 public static function favCount( $id ) {
2318 $ufavs = maybe_unserialize( get_post_meta( $id, '__wpdm_favs', true ) );
2319 $pfc = is_array( $ufavs ) ? count( $ufavs ) : 0;
2320
2321 return $pfc;
2322 }
2323
2324 /**
2325 * @param $ID
2326 * @param $emails
2327 * @param string $names
2328 * @param int $usageLimit
2329 * @param int $expireTime
2330 *
2331 * @usage mail package link to specified email address
2332 * @since 4.7.4
2333 */
2334 static function emailDownloadLink( $ID, $emails, $names = '', $usageLimit = 3, $expireTime = 604800 ) {
2335 if ( ! is_array( $emails ) ) {
2336 $emails = explode( ",", $emails );
2337 }
2338 if ( ! is_array( $names ) ) {
2339 $names = explode( ",", $names );
2340 }
2341 $title = get_the_title( $ID );
2342 $banner = get_the_post_thumbnail_url( $ID, array( 600, 400 ) );
2343 $logo = get_site_icon_url();
2344 foreach ( $emails as $index => $email ) {
2345 $download_link = WPDM()->package->expirableDownloadLink( $ID, $usageLimit, $expireTime, false );
2346 $download_page_link = WPDM()->package->expirableDownloadPage( $ID, $usageLimit, $expireTime, false );
2347 $params = array(
2348 'to_email' => $email,
2349 'name' => isset( $names[ $index ] ) ? $names[ $index ] : '',
2350 'package_name' => $title,
2351 'download_url' => $download_link,
2352 'download_page_url' => $download_page_link,
2353 'img_logo' => $logo,
2354 'banner' => $banner
2355 );
2356 \WPDM\__\Email::send( "email-lock", $params );
2357 }
2358 }
2359
2360 /**
2361 * Check if specified link or page template have the tag
2362 *
2363 * @param null $template
2364 * @param $tag
2365 *
2366 * @return bool|string
2367 */
2368 static function templateHasTag( $template = null, $tag = '' ) {
2369 if ( ! $template ) {
2370 return true;
2371 } else if ( is_string( $tag ) ) {
2372 return substr_count( $template, "[{$tag}]" );
2373 } else if ( is_array( $tag ) ) {
2374 foreach ( $tag as $t ) {
2375 if ( substr_count( $template, "[{$t}]" ) ) {
2376 return true;
2377 }
2378 }
2379 }
2380
2381 return false;
2382
2383 }
2384
2385 /**
2386 * Returns package icon
2387 *
2388 * @param $ID
2389 *
2390 * @return string
2391 */
2392 static function icon( $ID, $html = false, $class = '' ) {
2393 $icon = get_post_meta( $ID, '__wpdm_icon', true );
2394 if ( $icon == '' ) {
2395 $file_types = WPDM()->package->fileTypes( $ID, false );
2396 if ( count( $file_types ) ) {
2397 if ( count( $file_types ) == 1 ) {
2398 $tmpavar = $file_types;
2399 $ext = $tmpvar = array_shift( $tmpavar );
2400 } else {
2401 $ext = 'zip';
2402 }
2403 } else {
2404 $ext = "unknown";
2405 }
2406 if ( $ext === '' ) {
2407 $ext = 'wpdm';
2408 }
2409 $icon = FileSystem::fileTypeIcon( $ext );
2410 }
2411 if ( $html ) {
2412 $icon = "<img src='{$icon}' alt='Icon' class='$class' />";
2413 }
2414
2415 return apply_filters( "wpdm_package_icon", $icon, $ID );
2416 }
2417
2418 /**
2419 * Create a copy of a given package
2420 *
2421 * @param $ID
2422 *
2423 * @return int|\WP_Error
2424 */
2425 static function copy( $ID, $author = null, $new_meta = array() ) {
2426 $old_pack = (array) get_post( $ID );
2427 $package = array(
2428 'post_title' => $old_pack['post_title'],
2429 'post_content' => $old_pack['post_content'],
2430 'post_status' => $old_pack['post_status'],
2431 'comment_status' => $old_pack['comment_status'],
2432 'ping_status' => $old_pack['ping_status'],
2433 'post_type' => 'wpdmpro'
2434 );
2435
2436 if ( $author ) {
2437 $package['post_author'] = $author;
2438 }
2439 $new_ID = wp_insert_post( $package );
2440
2441 $meta = get_post_meta( $ID );
2442
2443 foreach ( $meta as $key => $value ) {
2444 foreach ( $value as $v ) {
2445 update_post_meta( $new_ID, $key, maybe_unserialize( $v ) );
2446 }
2447 }
2448 if ( is_array( $new_meta ) ) {
2449 foreach ( $new_meta as $key => $value ) {
2450 update_post_meta( $new_ID, $key, maybe_unserialize( $value ) );
2451 }
2452 }
2453
2454 $terms = get_the_terms( $ID, 'wpdmcategory' );
2455 foreach ( $terms as $term ) {
2456 wp_set_post_terms( $new_ID, (int)$term->term_id, 'wpdmcategory', true );
2457 }
2458
2459 $terms = get_the_terms( $ID, WPDM_TAG );
2460 foreach ( $terms as $term ) {
2461 wp_set_post_terms( $new_ID, $term->name, WPDM_TAG, true );
2462 }
2463
2464 return $new_ID;
2465 }
2466
2467 static function dummy() {
2468 $package = array(
2469 'post_title' => __( 'Sample Package', 'download-manager' ),
2470 'post_content' => 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. ',
2471 'excerpt' => 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s',
2472 'post_status' => 'publish',
2473 'download_link' => '<a href="#">Download</a>',
2474 'download_link_extended' => '<a href="#">Download</a>',
2475 );
2476
2477 return $package;
2478 }
2479
2480 /**
2481 * @param null $ID
2482 *
2483 * @return array Additional preview image urls
2484 */
2485 function additionalPreviews( $ID = null ) {
2486 $ID = $ID ? $ID : $this->ID;
2487 if ( ! $ID && is_singular( 'wpdmpro' ) ) {
2488 $ID = get_the_ID();
2489 }
2490 if ( ! $ID ) {
2491 return array();
2492 }
2493 $additional_previews = get_post_meta( $ID, '__wpdm_additional_previews', true );
2494 $previews = array();
2495 foreach ( $additional_previews as $media_id ) {
2496 $previews[] = wp_get_attachment_url( $media_id );
2497 }
2498
2499 return $previews;
2500 }
2501
2502 function getThumbnail( $ID, $FILEID, $size ) {
2503 if ( ! $this->files ) {
2504 $this->files = self::getFiles( $ID, true );
2505 }
2506 $file = wpdm_valueof( $this->files, $FILEID );
2507
2508 $imgext = array( 'png', 'jpg', 'jpeg', 'gif' );
2509 $ext = FileSystem::fileExt( $file );
2510 $thumb = '';
2511 $abspath = WPDM()->package->locateFile( $file );
2512
2513 if ( in_array( $ext, $imgext ) && $abspath ) {
2514 $thumb = FileSystem::imageThumbnail( $abspath, $size[0], $size[1], WPDM_USE_GLOBAL, true );
2515 } else if ( $ext === 'svg' ) {
2516 $thumb = str_replace( ABSPATH, home_url( '/' ), $file );
2517 } else if ( strtolower( $ext ) === 'pdf' && class_exists( 'Imagick' ) ) {
2518 $thumb = FileSystem::pdfThumbnail( $file, md5( $file ) );
2519 } else {
2520 $thumb = FileSystem::fileTypeIcon( $ext );
2521 }
2522
2523 return apply_filters( "wpdm_file_thumbnail", $thumb, [
2524 'file' => $file,
2525 'FILEID' => $FILEID,
2526 'ID' => $ID,
2527 'size' => $size
2528 ] );
2529 }
2530
2531 function locateFile( $file ) {
2532 if ( file_exists( $file ) ) {
2533 return $file;
2534 }
2535 if ( file_exists( UPLOAD_DIR . $file ) ) {
2536 return UPLOAD_DIR . $file;
2537 }
2538
2539 return false;
2540 }
2541
2542 function addViewCount() {
2543
2544 // Verify the request originated from a rendered package page. 'read' still
2545 // permits guests, so this does not gate legitimate visitors - it only stops
2546 // blind POSTs against this endpoint. Bails out via wp_send_json() on failure.
2547 __::isAuthentic( '__wpdm_view_count', NONCE_KEY, 'read', false );
2548
2549 $id = (int) __::valueof( $_REQUEST, 'id', [ 'default' => 0, 'validate' => 'int' ] );
2550
2551 // Only packages get a view count. Without this, any ID could be used to
2552 // create/increment __wpdm_view_count meta on arbitrary posts and pages.
2553 if ( $id <= 0 || get_post_type( $id ) !== 'wpdmpro' ) {
2554 wp_send_json( [
2555 'success' => false,
2556 'type' => 'error',
2557 'message' => __( 'Invalid package.', 'download-manager' )
2558 ], 400 );
2559 }
2560
2561 $views = (int) get_post_meta( $id, '__wpdm_view_count', true );
2562 update_post_meta( $id, '__wpdm_view_count', $views + 1 );
2563 wp_send_json( [ 'views' => $views + 1 ] );
2564 }
2565
2566
2567 /**
2568 * @usage Find similar packages
2569 *
2570 * @param null $package_id
2571 * @param int $count
2572 * @param bool|true $html
2573 *
2574 * @return array|bool|string
2575 */
2576 function similarPackages( $package_id = null, $count = 5, $html = true ) {
2577 $id = $package_id ? $package_id : get_the_ID();
2578 if ( is_array( $package_id ) ) {
2579 $id = $package_id['ID'];
2580 }
2581 $tags = wp_get_post_terms( $id, WPDM_TAG );
2582 $cats = wp_get_post_terms( $id, 'wpdmcategory' );
2583 $posts = array();
2584 if ( $tags ) {
2585 $tag_ids = array();
2586 foreach ( $tags as $individual_tag ) {
2587 $tag_ids[] = $individual_tag->term_id;
2588 }
2589 foreach ( $cats as $individual_cat ) {
2590 $cat_ids[] = $individual_cat->term_id;
2591 }
2592 $args = array(
2593 'post_type' => 'wpdmpro',
2594 'tax_query' => [
2595 [
2596 'taxonomy' => WPDM_TAG,
2597 'field' => 'id',
2598 'terms' => $tag_ids,
2599 'operator' => 'IN'
2600 ],
2601 [
2602 'taxonomy' => 'wpdmcategory',
2603 'field' => 'id',
2604 'terms' => $cat_ids,
2605 'operator' => 'IN'
2606 ],
2607 'relation' => 'OR'
2608 ],
2609 'post__not_in' => array( $id ),
2610 'posts_per_page' => $count
2611 );
2612
2613 $posts = get_posts( $args );
2614
2615 if ( ! $html ) {
2616 return $posts;
2617 }
2618
2619 $html = "";
2620 //Filter hook to change related packages/downloads template
2621 $template = apply_filters( "wpdm_replated_package_template", "link-template-panel.php", $package_id );
2622 $cols = apply_filters( "wpdm_replated_package_columns", 6, $package_id );
2623 foreach ( $posts as $p ) {
2624
2625 $package['ID'] = $p->ID;
2626 $package['post_title'] = $p->post_title;
2627 $package['post_content'] = $p->post_content;
2628 $package['post_excerpt'] = $p->post_excerpt;
2629 $html .= "<div class='col-md-{$cols}'>" . wpdm_fetch_template( $template, $package, 'link' ) . "</div>";
2630
2631 }
2632 }
2633 if ( count( $posts ) == 0 ) {
2634 $html = "<div class='col-md-12'><div class='alert alert-info'>" . __( "No related download found!", "download-manager" ) . "</div> </div>";
2635 }
2636 $html = "<div class='w3eden'><div class='row'>" . $html . "</div></div>";
2637 wp_reset_query();
2638
2639 return $html;
2640 }
2641
2642 function search( $keyword = '' ) {
2643 $keyword = wpdm_query_var( 'search' ) ?: $keyword;
2644 if ( $keyword ) {
2645 $query = new Query();
2646 $query->search( $keyword );
2647 if ( wpdm_query_var( 'premium', 'int' ) > 0 ) {
2648 $query->meta( '__wpdm_base_price', 0, '>' );
2649 $query->meta_relation( 'AND' );
2650 }
2651 $query->process();
2652 $packages = $query->packages();
2653 foreach ( $packages as &$package ) {
2654 $package = (object) [
2655 'ID' => $package->ID,
2656 'post_title' => $package->post_title,
2657 'post_content' => $package->post_content
2658 ];
2659 }
2660 if ( wpdm_query_var( 'premium', 'int' ) > 0 && function_exists( 'wpdmpp_product_license_options' ) ) {
2661 foreach ( $packages as &$package ) {
2662 $licenses = wpdmpp_product_license_options( $package->ID );
2663 $package->licenses = count( $licenses ) > 0 ? $licenses : null;
2664 }
2665 }
2666 wp_send_json( [ 'total' => $query->count, 'packages' => $packages, 'q' => $query->params ] );
2667 }
2668 }
2669
2670 /**
2671 * Display package changelog in a timeline format
2672 *
2673 * @param int $ID Package ID
2674 * @param array $args Optional arguments
2675 * @return string HTML output
2676 */
2677 public function changelog($ID = null, $args = [])
2678 {
2679 if (!$ID) {
2680 $ID = $this->ID;
2681 }
2682
2683 if (!$ID) {
2684 return '';
2685 }
2686
2687 // Default arguments
2688 $defaults = [
2689 'title' => __('Changelog', 'download-manager'),
2690 'show_empty' => false,
2691 'limit' => 0, // 0 = show all
2692 'collapsed' => true, // Collapse all except first
2693 ];
2694 $args = wp_parse_args($args, $defaults);
2695
2696 // Get changelog from post meta
2697 $changelog = get_post_meta($ID, '__wpdm_changelog', true);
2698 if (!is_array($changelog) || empty($changelog)) {
2699 if ($args['show_empty']) {
2700 return '<div class="wpdm-changelog-empty">' . esc_html__('No changelog available.', 'download-manager') . '</div>';
2701 }
2702 return '';
2703 }
2704
2705 // Sort by timestamp descending (newest first)
2706 usort($changelog, function($a, $b) {
2707 $ts_a = isset($a['timestamp']) ? $a['timestamp'] : 0;
2708 $ts_b = isset($b['timestamp']) ? $b['timestamp'] : 0;
2709 return $ts_b - $ts_a;
2710 });
2711
2712 // Apply limit if set
2713 if ($args['limit'] > 0) {
2714 $changelog = array_slice($changelog, 0, $args['limit']);
2715 }
2716
2717 // Build HTML output
2718 $html = '<div class="wpdm-changelog">';
2719
2720 if (!empty($args['title'])) {
2721 $html .= '<div class="wpdm-changelog__header">';
2722 $html .= '<h4 class="wpdm-changelog__title">';
2723 $html .= '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg>';
2724 $html .= esc_html($args['title']);
2725 $html .= '</h4>';
2726 $html .= '</div>';
2727 }
2728
2729 $html .= '<div class="wpdm-changelog__list">';
2730
2731 foreach ($changelog as $index => $entry) {
2732 $version = isset($entry['version']) ? esc_html($entry['version']) : '';
2733 $date = isset($entry['date']) ? esc_html($entry['date']) : '';
2734 $changes = isset($entry['changes']) ? wp_kses_post($entry['changes']) : '';
2735 $is_latest = ($index === 0);
2736 $is_collapsed = $args['collapsed'] && !$is_latest;
2737
2738 $html .= '<div class="wpdm-changelog__item' . ($is_latest ? ' wpdm-changelog__item--latest' : '') . ($is_collapsed ? ' wpdm-changelog__item--collapsed' : '') . '">';
2739
2740 // Timeline dot
2741 $html .= '<div class="wpdm-changelog__timeline">';
2742 $html .= '<div class="wpdm-changelog__dot' . ($is_latest ? ' wpdm-changelog__dot--latest' : '') . '"></div>';
2743 $html .= '<div class="wpdm-changelog__line"></div>';
2744 $html .= '</div>';
2745
2746 // Content
2747 $html .= '<div class="wpdm-changelog__content">';
2748
2749 // Header with version and date
2750 $html .= '<div class="wpdm-changelog__item-header" data-toggle="changelog">';
2751 $html .= '<div class="wpdm-changelog__meta">';
2752 $html .= '<span class="wpdm-changelog__version' . ($is_latest ? ' wpdm-changelog__version--latest' : '') . '">';
2753 $html .= '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"/><line x1="7" y1="7" x2="7.01" y2="7"/></svg>';
2754 $html .= 'v' . $version;
2755 if ($is_latest) {
2756 $html .= '<span class="wpdm-changelog__badge">' . esc_html__('Latest', 'download-manager') . '</span>';
2757 }
2758 $html .= '</span>';
2759 $html .= '<span class="wpdm-changelog__date">';
2760 $html .= '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>';
2761 $html .= $date;
2762 $html .= '</span>';
2763 $html .= '</div>';
2764 $html .= '<button type="button" class="wpdm-changelog__toggle" aria-expanded="' . ($is_collapsed ? 'false' : 'true') . '" aria-label="' . esc_attr__('Toggle details', 'download-manager') . '">';
2765 $html .= '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"/></svg>';
2766 $html .= '</button>';
2767 $html .= '</div>';
2768
2769 // Body with changes
2770 $html .= '<div class="wpdm-changelog__body">';
2771 $html .= '<div class="wpdm-changelog__changes">' . $changes . '</div>';
2772 $html .= '</div>';
2773
2774 $html .= '</div>'; // .wpdm-changelog__content
2775 $html .= '</div>'; // .wpdm-changelog__item
2776 }
2777
2778 $html .= '</div>'; // .wpdm-changelog__list
2779 $html .= '</div>'; // .wpdm-changelog
2780
2781 // Add inline JavaScript for toggle functionality.
2782 // This markup is emitted once per changelog, so the handler must be idempotent:
2783 // binding per-header would attach one listener per changelog on the page, and a
2784 // click would then toggle the class once per listener (i.e. cancel itself out
2785 // whenever a page holds an even number of changelogs). A single delegated
2786 // listener guarded by a flag also covers changelogs inserted later via AJAX.
2787 $html .= "
2788 <script>
2789 (function() {
2790 if (window.__wpdmChangelogBound) return;
2791 window.__wpdmChangelogBound = true;
2792 document.addEventListener('click', function(e) {
2793 if (!e.target || !e.target.closest) return;
2794 var header = e.target.closest('.wpdm-changelog [data-toggle=\"changelog\"]');
2795 if (!header) return;
2796 var item = header.closest('.wpdm-changelog__item');
2797 if (!item) return;
2798 var collapsed = item.classList.toggle('wpdm-changelog__item--collapsed');
2799 var toggle = header.querySelector('.wpdm-changelog__toggle');
2800 if (toggle) toggle.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
2801 });
2802 })();
2803 </script>";
2804
2805 return $html;
2806 }
2807
2808 /**
2809 * Static wrapper for changelog display
2810 *
2811 * @param int $ID Package ID
2812 * @param array $args Optional arguments
2813 * @return string HTML output
2814 */
2815 public static function getChangelog($ID, $args = [])
2816 {
2817 $controller = new self($ID);
2818 return $controller->changelog($ID, $args);
2819 }
2820
2821
2822 }
2823