← All changes
|
hello-wpstream/framework/wpstream-help-functions.php
+1
-129
4.14.1
→
4.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 . '&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 | } |