PluginProbe
WpStream – Live Streaming, Video on Demand, Pay Per View / 4.8.2
WpStream – Live Streaming, Video on Demand, Pay Per View v4.8.2
4.14.1 4.14.0 4.13.2 4.13.1 4.13 4.12.5 4.12.4 4.12.3 4.12.2 4.12.1 4.12 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 4.5 4.5.1 4.5.11 4.5.11.1 4.5.11.2 4.5.11.4 4.5.11.5 4.5.11.6 All 181 releases
← All changes | hello-wpstream/framework/wpstream-help-functions.php +1 -129 4.14.14.8.2 View file →
@@ -1,18 +1,6 @@
1 1 <?php
2 -/**
3 - * Theme helper / utility functions for the bundled hello-wpstream companion theme.
4 - *
5 - * @package Wpstream
6 - * @subpackage Wpstream/hello-wpstream
7 - */
8 2
9 -
10 -// Exit if accessed directly.
11 -if ( ! defined( 'ABSPATH' ) ) {
12 - exit;
13 -}
14 -
15 3 if ( ! function_exists( 'wpstream_theme_featured_image' ) ) {
16 4 /**
17 5 * Display the featured image for a post or page with additional functionality.
18 6 *
@@ -23,48 +11,34 @@
23 11 * @param bool $show_badge Optional. Show badge.
24 12 * @return string The HTML markup for the featured image.
25 13 */
26 14 function wpstream_theme_featured_image( $post_id, $size = 'full', $context = 'unit_card', $link = false, $show_badge = false ) {
27 - // Start with the theme's fallback cover image in case the post has none.
28 15 $featured_image_src = wpstream_theme_default_card_no_image_url( $size );
29 - // Attachment ID of the post's featured image (0 when none is set).
30 16 $featured_image_id = get_post_thumbnail_id( $post_id );
31 - // Alt text stored on the featured image attachment (used for the <img alt>).
32 17 $featured_image_alt = get_post_meta( $featured_image_id, '_wp_attachment_image_alt', true );
33 18
34 19 // Check if a featured image is set for the current post or page.
35 20
36 - // When a real thumbnail exists, override the fallback with its URL.
37 21 if ( has_post_thumbnail( $post_id ) ) {
38 22 $featured_image_src = get_the_post_thumbnail_url( $post_id, $size );
39 23 }
40 24
41 - // Optional short preview clip attached to the post (empty string when absent).
42 25 $video_attachment_id = get_post_meta( $post_id, 'video_preview', true );
43 26
44 - // Open the thumbnail wrapper that all card markup is built inside.
45 27 $return_string = '<div class="post-thumbnail wpstream_featured_image">';
46 28
47 - // When linking is requested, wrap the whole card in an anchor to the post.
48 29 if ( $link ) {
49 30 $return_string .= '<a class="d-block w-100 h-100" href="' . esc_url( get_permalink( $post_id ) ) . '">';
50 31 }
51 32
52 - // Card contexts that support an inline hover/preview video AND actually have a clip:
53 - // render a muted <video> instead of a plain image.
54 33 if ( ('unit_card' === $context || 'video_preview' === $context ) && '' !== $video_attachment_id ) {
55 - // Unique DOM id so multiple preview players on one page don't collide.
56 34 $video_id = 'wpstream_unit_video_preview_' . wp_rand( 0, 99999999 );
57 35
58 - // Re-read the preview attachment ID (kept for clarity of the source meta).
59 36 $video_attachment_id = get_post_meta( $post_id, 'video_preview', true );
60 37
61 - // Resolve the preview clip's file URL for the <source> element.
62 38 $video_src = wp_get_attachment_url( $video_attachment_id );
63 - // Only the dedicated "video_preview" context shows a play overlay by default.
64 39 $play_button = $context === 'video_preview' ? '<div class="wpstream_video_unit_video_play">' . wpstream_theme_get_svg_icon('play_icon_white.svg') . '</div>' : "";
65 40
66 - // Blog posts get a themed "blog hover" icon rather than the generic play icon.
67 41 if ($context === 'video_preview' && get_post_type($post_id) === 'post'){
68 42 $play_button = '<div class="wpstream_video_unit_video_play">' . wpstream_theme_get_svg_icon('bloghover.svg') . '</div>';
69 43 }
70 44
@@ -69,10 +43,8 @@
69 43 }
70 44
71 45
72 46
73 - // Append the preview-video markup: play button, hover overlay and the muted
74 - // <video> element whose poster is the featured image and source is the clip.
75 47 $return_string .= '<div class="wpstream_video_unit_video_wrapper wpstream_video_unit_video_wrapper_trigger"
76 48 data-video-id="'. esc_attr( $video_id ).'">'
77 49
78 50 . $play_button
@@ -83,11 +55,8 @@
83 55 </video>
84 56
85 57 </div>';
86 58 } else {
87 - // No preview clip: render a still image card instead.
88 - // Blog posts and non-video products use the "blog hover" icon; video products
89 - // (VOD/live) use the white play icon.
90 59 if( get_post_type($post_id) === 'post' || !wpstream_is_woo_video_product( $post_id ) ){
91 60 $play_button = '<div class="wpstream_video_unit_video_play">' . wpstream_theme_get_svg_icon('bloghover.svg') . '</div>';
92 61 }else{
93 62 $play_button = '<div class="wpstream_video_unit_video_play">' . wpstream_theme_get_svg_icon('play_icon_white.svg') . '</div>';
@@ -93,24 +62,18 @@
93 62 $play_button = '<div class="wpstream_video_unit_video_play">' . wpstream_theme_get_svg_icon('play_icon_white.svg') . '</div>';
94 63 }
95 64
96 65
97 - // Overlay + play button + the featured image (alt falls back to the post title).
98 66 $return_string .= '<div class="wpstream_video_unit_overlay"></div>'. $play_button .'<img src="' . esc_url( $featured_image_src ) . '" alt="' . esc_attr( ! empty( $featured_image_alt ) ? $featured_image_alt : get_the_title( $post_id ) ) . '" class="wpstream_featured_unit_cards" />';
99 67 }
100 68
101 - // Close the wrapping anchor when the card was made clickable.
102 69 if ( $link ) {
103 70 $return_string .= '</a>';
104 71 }
105 72
106 - // On unit cards (or when a badge is forced) show the view/read counter.
107 73 if ( 'unit_card' === $context || $show_badge ) {
108 - // Cached view count stored as post meta.
109 74 $views = intval( get_post_meta( $post_id, 'post_view_count', true ) );
110 - // Default label for blog-style content is "reads".
111 75 $views_label = __( 'reads', 'hello-wpstream' );
112 - // Product / video post types use "views" instead.
113 76 if ( in_array(
114 77 get_post_type( $post_id ),
115 78 array(
116 79 'wpstream_product_vod',
@@ -121,24 +84,19 @@
121 84 true
122 85 ) ) {
123 86 $views_label = __( 'views', 'hello-wpstream' );
124 87 }
125 - // Append the counter badge.
126 88 $return_string .= '<div class="wpstream_featured_image_views">' . $views . ' ' . esc_html( $views_label ) . '</div>';
127 89 }
128 90
129 - // For live-stream products / free live events, add a "LIVE" tag when the current
130 - // user actually has this event live right now.
131 91 if ( ( get_post_type( $post_id ) === 'product' && has_term( 'live_stream', 'product_type', $post_id ) || get_post_type( $post_id ) === 'wpstream_product' ) ) {
132 92
133 - // Map of the current user's live events keyed by post ID.
134 - $live_events = wpestream_integrations_get_current_user_live_events();
93 + $live_events = wpestream_integrations_get_current_user_live_events('no');
135 94 if ( is_array( $live_events) && array_key_exists( $post_id, $live_events ) ) {
136 95 $return_string .= '<div class="wpstream_featured_image_live_tag">' . esc_html_x( 'LIVE', 'Card tag', 'hello-wpstream' ) . '</div>';
137 96 }
138 97 }
139 98
140 - // Close the thumbnail wrapper and hand back the assembled markup.
141 99 $return_string .= '</div><!-- .post-thumbnail -->';
142 100
143 101 return $return_string;
144 102 }
@@ -151,9 +109,8 @@
151 109 * @param string $size The size of the card image.
152 110 * @return string The URL of the default image.
153 111 */
154 112 function wpstream_theme_default_card_no_image_url( $size ) {
155 - // Bundle cards use a larger default cover; everything else uses the standard one.
156 113 if ( 'wpstream_bundle_unit_cards_image' === $size ) {
157 114 $image_path = '/img/default-cover-big.png';
158 115 } else {
159 116 $image_path = '/img/default-cover.png';
@@ -174,14 +131,12 @@
174 131 * @param string $icon_path The path to the SVG icon file.
175 132 * @return string|false The SVG content or false if the file doesn't exist.
176 133 */
177 134 function wpstream_theme_get_svg_icon( $icon_path ) {
178 - // Resolve the icon name to an absolute path under the theme's icon folder.
179 135 $icon_path = get_template_directory() . '/img/icons/' . $icon_path;
180 136
181 137 // Check if the file exists.
182 138 if ( file_exists( $icon_path ) ) {
183 - // Buffer the included SVG file so its raw markup can be returned as a string.
184 139 ob_start();
185 140 include $icon_path;
186 141
187 142 return ob_get_clean();
@@ -190,9 +145,8 @@
190 145 }
191 146 }
192 147 }
193 148
194 -if ( ! function_exists( 'wpstream_get_count_like_post' ) ) :
195 149 /**
196 150 * Get the count of likes for a specific post.
197 151 *
198 152 * @param int $post_id The ID of the post.
@@ -198,12 +152,10 @@
198 152 * @param int $post_id The ID of the post.
199 153 * @return int The count of likes for the post.
200 154 */
201 155 function wpstream_get_count_like_post( $post_id ) {
202 - // Read the accumulated like counter stored in post meta and cast it to an int.
203 156 return intval( get_post_meta( $post_id, 'wpstream_like_items', true ) );
204 157 }
205 -endif;
206 158
207 159 if ( ! function_exists( 'wpstream_query_arguments_add_order_by' ) ) {
208 160 /**
209 161 * Generate query arguments for ordering posts.
@@ -211,15 +163,12 @@
211 163 * @param int $order The order value.
212 164 * @return array An array containing the query arguments and transient appendix.
213 165 */
214 166 function wpstream_query_arguments_add_order_by( $order ) {
215 - // Sensible defaults: newest-first by post ID, no meta key involved.
216 167 $meta_directions = 'DESC';
217 168 $meta_order = '';
218 169 $order_by = 'ID';
219 170
220 - // Translate the numeric $order code into WP_Query orderby/order (and a meta key
221 - // for meta-based sorts such as views, price and likes).
222 171 switch ( $order ) {
223 172 case 1:
224 173 $meta_order = '';
225 174 $meta_directions = 'DESC';
@@ -276,32 +225,26 @@
276 225 $order_by = 'rand';
277 226 break;
278 227 }
279 228
280 - // Build a cache-key suffix that uniquely reflects this sort choice.
281 229 $transient_appendix = '_' . $meta_order . '_' . $meta_directions;
282 230
283 - // Order 0 is the user's manual ordering; mark its cache key distinctly.
284 231 if ( 0 === $order ) {
285 232 $transient_appendix .= '_myorder';
286 233 }
287 234
288 - // Base query-args always carry the orderby column.
289 235 $order_array = array(
290 236 'orderby' => $order_by,
291 237 );
292 238
293 - // Add the meta key only for meta-value based sorts.
294 239 if ( '' !== $meta_order ) {
295 240 $order_array['meta_key'] = $meta_order;//phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
296 241 }
297 242
298 - // Add the sort direction when one is defined.
299 243 if ( '' !== $meta_directions ) {
300 244 $order_array['order'] = $meta_directions;
301 245 }
302 246
303 - // Return both the WP_Query fragment and the cache-key suffix.
304 247 return array(
305 248 'order_array' => $order_array,
306 249 'transient_appendix' => $transient_appendix,
307 250 );
@@ -316,18 +259,14 @@
316 259 * @param string $selected_option The selected option.
317 260 * @return string The HTML for the select dropdown.
318 261 */
319 262 function wpstream_post_type_options_select( $attributes, $selected_option = '' ) {
320 - // Available post-type choices (label => translated text).
321 263 $options = wpstream_post_type_options();
322 264
323 - // Static field identifiers/classes for the AJAX-triggering dropdown.
324 265 $name = 'post_type';
325 266 $class = 'wpstream_dropdown_select wpstream_dropdown_select_trigger_ajax wpstream_dropdown_select_post_type';
326 267 $id = 'post_type_dropdown';
327 - // Visible label comes from the caller's attributes.
328 268 $label = $attributes['label_post_types'];
329 - // Delegate the actual markup to the shared custom-dropdown builder.
330 269 $output = wpstream_create_custom_dropdown( $options, $name, $class, $id, $label, $selected_option );
331 270
332 271
333 272 return $output;
@@ -340,9 +279,8 @@
340 279 *
341 280 * @return array An associative array of post type options.
342 281 */
343 282 function wpstream_post_type_options() {
344 - // Map each selectable post type to its human-readable, translated label.
345 283 $options = array(
346 284 'product' => esc_html__( 'Products', 'hello-wpstream' ),
347 285 'wpstream_bundles' => esc_html__( 'Bundles', 'hello-wpstream' ),
348 286 'wpstream_product_vod' => esc_html__( 'Free Vod', 'hello-wpstream' ),
@@ -360,24 +298,19 @@
360 298 * @param int $product_id The ID of the product.
361 299 * @return bool True if the product is a video product, false otherwise.
362 300 */
363 301 function wpstream_is_woo_video_product( $product_id ) {
364 - // WooCommerce product types that WpStream considers "video" products.
365 302 $wpstream_woo_product_types = ['video_on_demand', 'live_stream', 'wpstream_bundle', 'subscription'];
366 303
367 - // Without WooCommerce there are no such products.
368 304 if ( ! function_exists( 'wc_get_product' ) ) {
369 305 return false;
370 306 }
371 - // Load the product object for the given ID.
372 307 $product = wc_get_product( $product_id );
373 308
374 - // Guard against an invalid / non-existent product.
375 309 if ( ! $product ) {
376 310 return false;
377 311 }
378 312
379 - // True only when the product's type is one of the recognised video types.
380 313 return in_array( $product->get_type(), $wpstream_woo_product_types, true );
381 314 }
382 315 }
383 316
@@ -389,9 +322,8 @@
389 322 */
390 323 if ( ! function_exists( 'wpstream_get_card_type_path' ) ) {
391 324 function wpstream_get_card_type_path($card_type)
392 325 {
393 - // Resolve a card template name to its absolute path inside the theme folder.
394 326 return WPSTREAM_PLUGIN_PATH . 'hello-wpstream/' . $card_type;
395 327 }
396 328 }
397 329
@@ -407,10 +339,8 @@
407 339 function wpstream_get_all_items_list( $limit = -1, $post_type = 'free', $ids = array() ) {
408 340
409 341 $options = array();
410 342
411 - // "free" means the two free WpStream post types with no taxonomy filter;
412 - // anything else targets WooCommerce products (live/VOD or type-less products).
413 343 if ( 'free' === $post_type ) {
414 344 $post_type = array( 'wpstream_product_vod', 'wpstream_product' );
415 345 $taxonomy_array = array();
416 346 } else {
@@ -432,9 +362,8 @@
432 362 );
433 363
434 364 }
435 365
436 - // Base query: chosen post type(s), row limit and any taxonomy constraint.
437 366 $args = array(
438 367 'post_type' => $post_type,
439 368 'posts_per_page' => $limit,
440 369 'tax_query' => $taxonomy_array, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
@@ -439,20 +368,17 @@
439 368 'posts_per_page' => $limit,
440 369 'tax_query' => $taxonomy_array, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
441 370 );
442 371
443 - // When explicit IDs are supplied, restrict to them and preserve their order.
444 372 if ( ! empty( $ids ) ) {
445 373 $args['post__in'] = $ids;
446 374 $args['orderby'] = 'post__in';
447 375 }
448 376
449 - // Run the query.
450 377 $custom_post_types = get_posts( $args );
451 378
452 379 $options = array();
453 380
454 - // Reduce each post to a compact title/type entry keyed by post ID.
455 381 foreach ( $custom_post_types as $custom_post ) {
456 382
457 383 $options[ $custom_post->ID ] = array(
458 384 'title' => $custom_post->post_title,
@@ -467,16 +393,10 @@
467 393
468 394 if ( ! function_exists( 'wstream_sort_options_array' ) ) {
469 395 /**
470 396 * Sort options array
471 - *
472 - * Builds the label list for the listing "sort by" dropdown. Each key is the
473 - * numeric order code consumed by wpstream_query_arguments_add_order_by().
474 - *
475 - * @return array Order-code => translated label.
476 397 */
477 398 function wstream_sort_options_array() {
478 - // Order codes mapped to their human-readable, translated dropdown labels.
479 399 $listing_filter_array = array(
480 400 '1' => esc_html__( 'Newest first', 'hello-wpstream' ),
481 401 '2' => esc_html__( 'Oldest first', 'hello-wpstream' ),
482 402 '5' => esc_html__( 'Views High to Low', 'hello-wpstream' ),
@@ -502,26 +422,21 @@
502 422 * @return bool
503 423 */
504 424 function wpstream_theme_is_show_sidebar( $post_id = null ) {
505 425 $is_show_sidebar=null;
506 - // Prefer a per-post override stored via Meta Box, when that plugin is active.
507 426 if(function_exists('rwmb_meta')){
508 427 $is_show_sidebar = rwmb_meta( 'wpstream_theme_show_sidebar_on_post', array(), $post_id );
509 428 }
510 - // If the per-post override is set, honour it ('1' => show).
511 429 if ( '' !== $is_show_sidebar ) {
512 430 return '1' === $is_show_sidebar;
513 431 } else {
514 - // Otherwise fall back to a per-post-type default.
515 432 $post_type = get_post_type( $post_id );
516 433
517 434 switch ( $post_type ) {
518 435 case 'post':
519 - // Blog posts use the customizer sidebar setting (default: on).
520 436 $wpstream_show_sidebar = get_theme_mod( 'wpstream_blog_post_sidebar', true );
521 437 break;
522 438 default:
523 - // Other post types default to off, but allow a filter override.
524 439 $wpstream_show_sidebar = apply_filters( 'wpstream_show_sidebar_for_post_type', false, $post_type );
525 440 break;
526 441 }
527 442
@@ -540,9 +455,8 @@
540 455 * @return string The HTML markup for the featured image.
541 456 */
542 457 function wpstream_theme_featured_image_simple( $post_id, $size = 'full', $context = 'unit_card' ) {
543 458
544 - // Start from the default cover; replaced below when a real thumbnail exists.
545 459 $featured_image_src = wpstream_theme_default_card_no_image_url( $size );
546 460
547 461 // Check if a featured image is set for the current post or page.
548 462 if ( has_post_thumbnail( $post_id ) ) {
@@ -548,21 +462,17 @@
548 462 if ( has_post_thumbnail( $post_id ) ) {
549 463 $featured_image_src = get_the_post_thumbnail_url( $post_id, $size );
550 464 }
551 465
552 - // Open the thumbnail wrapper.
553 466 $return_string = '<div class="post-thumbnail wpstream_featured_image">';
554 467
555 - // Simple variant: just the image, no preview video or play overlay.
556 468 $return_string .= '<img src="' . esc_url( $featured_image_src ) . '" class="wpstream_featured_unit_cards rounded mb-3" />';
557 469
558 - // On unit cards, append the view counter.
559 470 if ( 'unit_card' === $context ) {
560 471 $views = intval( get_post_meta( $post_id, 'post_view_count', true ) );
561 472 $return_string .= '<div class="wpstream_featured_image_views">' . $views . ' ' . esc_html__( 'views', 'hello-wpstream' ) . '</div>';
562 473 }
563 474
564 - // Close the wrapper and return the markup.
565 475 $return_string .= '</div><!-- .post-thumbnail -->';
566 476
567 477 return $return_string;
568 478 }
@@ -570,23 +480,15 @@
570 480
571 481 if ( ! function_exists( 'wpstream_generate_user_menu' ) ) {
572 482 /**
573 483 * Generate user menu
574 - *
575 - * Builds the "My Account" navigation list. Uses WooCommerce's account menu
576 - * items when WooCommerce is active, otherwise a minimal built-in menu. Each
577 - * entry is prefixed with its themed SVG icon.
578 - *
579 - * @return string HTML markup for the account menu links.
580 484 */
581 485 function wpstream_generate_user_menu() {
582 486 $return_string = '';
583 487
584 - // Map each known account endpoint to its inline SVG icon markup.
585 488 $svg_icons = [
586 489 'dashboard' => wpstream_theme_get_svg_icon('dashboard.svg'),
587 490 'orders' => wpstream_theme_get_svg_icon('orders-icon.svg'),
588 - 'downloads' => wpstream_theme_get_svg_icon('downloads.svg'),
589 491 'subscriptions' => wpstream_theme_get_svg_icon('orders-subscription.svg'),
590 492 'edit-address' => wpstream_theme_get_svg_icon('location-icon.svg'),
591 493 'edit-account' => wpstream_theme_get_svg_icon('edit-account-icon.svg'),
592 494 'event-list' => wpstream_theme_get_svg_icon('purchased-events-icon.svg'),
@@ -596,24 +498,19 @@
596 498 'customer-logout' => wpstream_theme_get_svg_icon('logout_icon.svg'),
597 499 'logout' => wpstream_theme_get_svg_icon('logout_icon.svg'),
598 500 ];
599 501
600 - // Buffer the markup so it can be returned as a string.
601 502 ob_start();
602 503
603 - // Preferred path: WooCommerce provides the canonical account menu items.
604 504 if ( function_exists( 'wc_get_account_menu_items' ) ) {
605 505 $menu_items = wc_get_account_menu_items();
606 506
607 - // Hide the "Go Live" entry for users without streaming permission.
608 507 if ( ! wpstream_check_if_user_can_stream()) {
609 508 unset($menu_items['start-streaming']);
610 509 }
611 510
612 - // Render each endpoint as an account list-group link.
613 511 foreach ( $menu_items as $endpoint => $label ) :
614 512 $menu_link= wc_get_account_endpoint_url( $endpoint ) ;
615 - // Subscriptions are served from the theme dashboard, not the Woo endpoint.
616 513 if($endpoint === 'subscriptions') {
617 514 $menu_link = home_url('/dashboard/subscriptions/');
618 515 }
619 516 ?>
@@ -624,9 +521,8 @@
624 521 <?php
625 522 endforeach;
626 523
627 524 } else {
628 - // Fallback path (no WooCommerce): a minimal built-in account menu.
629 525 $menu_items = array(
630 526 'dashboard' => esc_html__( 'Dashboard', 'hello-wpstream' ),
631 527 'start-streaming' => esc_html__( 'Go Live', 'hello-wpstream' ),
632 528 'edit-account' => esc_html__( 'Edit Account', 'hello-wpstream' ),
@@ -633,17 +529,14 @@
633 529 'watch-later' => esc_html__( 'Watch Later', 'hello-wpstream' ),
634 530 'logout' => esc_html__( 'Logout', 'hello-wpstream' ),
635 531 );
636 532
637 - // Same streaming-permission gate as the WooCommerce branch.
638 533 if ( ! wpstream_check_if_user_can_stream()) {
639 534 unset($menu_items['start-streaming']);
640 535 }
641 536
642 - // Render each endpoint, resolving links via the non-Woo helper.
643 537 foreach ( $menu_items as $endpoint => $label ) :
644 538 $item_link = wpstream_non_woo_get_account_endpoint_url( $endpoint );
645 - // Logout needs the real WordPress logout URL (with redirect home).
646 539 if ( 'logout' === $endpoint ) {
647 540 $item_link = wp_logout_url( home_url() );
648 541 }
649 542 ?>
@@ -658,9 +551,8 @@
658 551 endforeach;
659 552
660 553 }
661 554
662 - // Capture the buffered menu markup and clean the buffer.
663 555 $return_string = ob_get_contents();
664 556
665 557 ob_end_clean();
666 558
@@ -693,9 +585,8 @@
693 585 );
694 586
695 587 // Loop through each customer order.
696 588 foreach ( $customer_orders as $customer_order ) {
697 - // Order line items and order-level metadata (id + created date).
698 589 $order_items = $customer_order->get_items();
699 590 $order = wc_get_order( $customer_order );
700 591 $order_id = $order->get_id();
701 592 $order_date = $order->get_date_created();
@@ -700,15 +591,12 @@
700 591 $order_id = $order->get_id();
701 592 $order_date = $order->get_date_created();
702 593 $formatted_date = wc_format_datetime( $order_date );
703 594
704 - // Inspect each line item in the order.
705 595 foreach ( $order_items as $item ) {
706 596 $product = $item->get_product();
707 597
708 - // Keep only products matching the requested type.
709 598 if ( $product && $product_type === $product->get_type() ) {
710 - // Record what was paid plus the order context for this product.
711 599 $total_paid = $item->get_total();
712 600 $temp_array = array(
713 601 'price' => $total_paid,
714 602 'order_id' => $order_id,
@@ -715,15 +603,13 @@
715 603 'order_date' => $formatted_date,
716 604 'product' => $product,
717 605 );
718 606
719 - // Key by product ID so duplicate purchases collapse to one entry.
720 607 $all_products[$product->get_id()] = $temp_array;
721 608 }
722 609 }
723 610 }
724 611
725 - // per_page of -1 means "return everything" without pagination.
726 612 if(intval($per_page) === -1){
727 613 return $all_products;
728 614 }
729 615
@@ -728,12 +614,10 @@
728 614 }
729 615
730 616 // Calculate offset for pagination.
731 617 $offset = ( $page - 1 ) * $per_page;
732 - // Slice out just the requested page of products.
733 618 $paginated_products = array_slice( $all_products, $offset, $per_page );
734 619
735 - // Return the page plus total counts for building pagination controls.
736 620 return array(
737 621 'products' => $paginated_products,
738 622 'total' => count( $all_products ),
739 623 'max_num_pages' => ceil( count( $all_products ) / $per_page ),
@@ -748,17 +632,14 @@
748 632 * @param string $endpoint Optional. Endpoint to append to the URL.
749 633 * @return string URL for the account endpoint.
750 634 */
751 635 function wpstream_non_woo_get_account_endpoint_url( $endpoint = '' ) {
752 - // Base URL is the theme's dashboard page.
753 636 $url = wpstream_return_dashboard_page();
754 637
755 - // Append the endpoint as a query arg when one is given.
756 638 if ( $endpoint ) {
757 639 $url = add_query_arg( 'endpoint', $endpoint, $url );
758 640 }
759 641
760 - // Return a sanitised URL safe for storage/output.
761 642 return esc_url_raw( $url );
762 643 }
763 644 }
764 645
@@ -771,9 +652,8 @@
771 652 * @param int $is_single Optional. Whether the post is single or not. Default is 1 (true).
772 653 * @return string The HTML markup for the social share buttons.
773 654 */
774 655 function wpstream_theme_show_social_share_page( $post_id, $size = 'full', $is_single = 1 ) {
775 - // Thin wrapper: open a container, delegate to the share-buttons builder, close it.
776 656 $return_string = '<div class="wpstream-social-share-wrapper">';
777 657 $return_string .= wpstream_share_unit_desing( $post_id, $size, $is_single );
778 658 $return_string .= '</div>';
779 659
@@ -790,21 +670,17 @@
790 670 * @param int $is_single Optional. Whether the post is single or not. Default is 0 (false).
791 671 * @return string The HTML markup for the social share buttons.
792 672 */
793 673 function wpstream_share_unit_desing( $post_id, $size = 'full', $is_single = 0 ) {
794 - // Gather the pieces every share URL needs: scheme, image, permalink and title.
795 674 $protocol = is_ssl() ? 'https' : 'http';
796 675 $pinterest = wp_get_attachment_image_src( get_post_thumbnail_id( $post_id ), $size );
797 676 $link = esc_url( get_permalink( $post_id ) );
798 677 $title = get_the_title( $post_id );
799 - // Pre-encoded payloads for the Twitter/X intent and the mailto link.
800 678 $twitter_status = rawurlencode( $title . ' ' . $link );
801 679 $email_link = 'subject=' . rawurlencode( $title ) . '&body=' . rawurlencode( esc_url( $link ) );
802 680
803 - // Buffer the button markup for return as a string.
804 681 ob_start();
805 682
806 - // Text labels default to empty (icon-only) ...
807 683 $facebook_label = '';
808 684 $twitter_label = '';
809 685 $pinterest_label = '';
810 686 $whatsup_label = '';
@@ -809,9 +685,8 @@
809 685 $pinterest_label = '';
810 686 $whatsup_label = '';
811 687 $email_label = '';
812 688
813 - // ... and are filled in only on single/detail pages where labels are wanted.
814 689 if ( intval( $is_single ) === 1 ) {
815 690 $facebook_label = esc_html__( 'Facebook', 'hello-wpstream' );
816 691 $twitter_label = esc_html__( 'Twitter', 'hello-wpstream' );
817 692 $pinterest_label = esc_html__( 'Pinterest', 'hello-wpstream' );
@@ -818,9 +693,8 @@
818 693 $whatsup_label = esc_html__( 'WhatsApp', 'hello-wpstream' );
819 694 $email_label = esc_html__( 'Email', 'hello-wpstream' );
820 695 }
821 696
822 - // WhatsApp share text (title + permalink) and its wa.me deep link.
823 697 $text_whats = get_the_title( $post_id ) . ' ' . esc_url( get_permalink( $post_id ) );
824 698
825 699 $whatsup_link = 'https://wa.me/?text=' . ( $text_whats );
826 700
@@ -825,9 +699,8 @@
825 699 $whatsup_link = 'https://wa.me/?text=' . ( $text_whats );
826 700
827 701 ?>
828 702
829 - <!-- Social share buttons: each anchor opens the matching network's share dialog (or a mailto). Icons are inline SVG; labels only render on single pages. -->
830 703 <div class="share_unit">
831 704 <a href="<?php echo esc_url( $protocol . '://www.facebook.com/sharer.php?u=' . $link . '&amp;t=' . rawurlencode( get_the_title() ) ); ?>"
832 705 target="_blank" rel="noreferrer noopener nofollow" class="social_facebook d-flex align-items-center">
833 706
@@ -872,8 +745,7 @@
872 745 </a>
873 746 </div>
874 747 <?php
875 748
876 - // Return the buffered share-buttons markup.
877 749 return ob_get_clean();
878 750 }
879 751 }