From 92574d2c65f1d73811522fed975bbbcb145f233b Mon Sep 17 00:00:00 2001 From: rmens Date: Sat, 2 Nov 2024 15:49:30 +0100 Subject: [PATCH] Poging 6 --- lib/teksttv.php | 404 ++++++++++++++++++++++++++---------------------- 1 file changed, 223 insertions(+), 181 deletions(-) diff --git a/lib/teksttv.php b/lib/teksttv.php index b8b4bba..a542cc8 100644 --- a/lib/teksttv.php +++ b/lib/teksttv.php @@ -1,185 +1,209 @@ 20000, // 20 seconds for text slides + 'image' => 7000, // 7 seconds for image slides + 'ad_transition' => 5000 // 5 seconds for ad transitions + ]; + + /** + * Singleton pattern implementatie + */ + public static function get_instance() { + if (null === self::$instance) { + self::$instance = new self(); + } + return self::$instance; + } + + /** + * Constructor - initialiseert de API + */ + private function __construct() + { + $this->wp_timezone = new DateTimeZone(wp_timezone_string()); add_action('rest_api_init', [$this, 'register_api_routes']); } - // Register custom API routes for TekstTV slides and ticker messages + /** + * Registreert de API endpoints + */ public function register_api_routes() { register_rest_route('zw/v1', '/teksttv-slides', [ - 'methods' => \WP_REST_Server::READABLE, - 'callback' => [$this, 'get_slides'], - 'permission_callback' => '__return_true', + 'methods' => 'GET', + 'callback' => [$this, 'get_slides'], + 'permission_callback' => '__return_true' ]); register_rest_route('zw/v1', '/teksttv-ticker', [ - 'methods' => \WP_REST_Server::READABLE, - 'callback' => [$this, 'get_ticker_messages'], - 'permission_callback' => '__return_true', + 'methods' => 'GET', + 'callback' => [$this, 'get_ticker_messages'], + 'permission_callback' => '__return_true' ]); } - // Callback for the '/teksttv-slides' endpoint - generates an array of slides + /** + * Haalt alle slides op voor de TekstTV weergave + */ public function get_slides() { - $slides = []; + if (!function_exists('get_field')) { + return new WP_REST_Response([ + 'slides' => [], + '_debug' => $this->get_debug_info(), + 'error' => 'ACF plugin is niet actief' + ], 200); + } - // Check if Advanced Custom Fields (ACF) plugin is active and the 'teksttv_blokken' field exists - if (function_exists('get_field')) { - $blocks = get_field('teksttv_blokken', 'option'); - $ad_campaigns = $this->get_ad_campaigns(); - - // If blocks are available, process each one - if ($blocks) { - foreach ($blocks as $block) { - switch ($block['acf_fc_layout']) { - case 'blok_artikelen': - $slides = array_merge($slides, $this->get_article_slides($block)); - break; - case 'blok_afbeelding': - $image_slide = $this->get_image_slide($block); - if ($image_slide) { - $slides[] = $image_slide; - } - break; - case 'blok_reclame': - $slides = array_merge($slides, $this->get_ad_slides($block, $ad_campaigns)); - break; - case 'blok_fm_programmering': - // Placeholder for FM programming slides (not yet implemented) - break; - } + $blocks = get_field('teksttv_blokken', 'option') ?: []; + $slides = $this->process_blocks($blocks); + + return new WP_REST_Response([ + 'slides' => $slides, + '_debug' => $this->get_debug_info() + ], 200); + } + + /** + * Verwerkt verschillende type content blokken naar slides + */ + private function process_blocks($blocks) + { + $slides = []; + $ad_campaigns = $this->get_ad_campaigns(); + + if ($blocks) { + foreach ($blocks as $block) { + switch ($block['acf_fc_layout']) { + case 'blok_artikelen': + $slides = array_merge($slides, $this->get_article_slides($block)); + break; + case 'blok_afbeelding': + $image_slide = $this->get_image_slide($block); + if ($image_slide) { + $slides[] = $image_slide; + } + break; + case 'blok_reclame': + $slides = array_merge($slides, $this->get_ad_slides($block, $ad_campaigns)); + break; } } } - return new WP_REST_Response($slides, 200); + return array_filter($slides); } - // Generate slides based on posts filtered by regions and categories + /** + * Genereert slides van artikelen + */ private function get_article_slides($block) { $slides = []; $args = [ - 'post_type' => 'post', + 'post_type' => 'post', 'posts_per_page' => $block['aantal_artikelen'], - 'meta_query' => [ + 'meta_query' => [ [ - 'key' => 'post_in_kabelkrant', - 'value' => '1', - 'compare' => '=', - ], - ], + 'key' => 'post_in_kabelkrant', + 'value' => '1', + 'compare' => '=' + ] + ] ]; // Add region filters if specified if (!empty($block['Regiofilter'])) { - $region_ids = array_map(function ($term) { - return $term->term_id; - }, $block['Regiofilter']); - $args['tax_query'][] = [ 'taxonomy' => 'regio', - 'field' => 'term_id', - 'terms' => $region_ids, + 'field' => 'term_id', + 'terms' => array_map(function ($term) { + return $term->term_id; + }, $block['Regiofilter']) ]; } // Add category filters if specified if (!empty($block['categoriefilter'])) { - $category_ids = array_map(function ($term) { - return $term->term_id; - }, $block['categoriefilter']); - $args['tax_query'][] = [ 'taxonomy' => 'category', - 'field' => 'term_id', - 'terms' => $category_ids, + 'field' => 'term_id', + 'terms' => array_map(function ($term) { + return $term->term_id; + }, $block['categoriefilter']) ]; } - // Run the custom query to fetch posts $query = new WP_Query($args); if ($query->have_posts()) { while ($query->have_posts()) { $query->the_post(); - $post_id = get_the_ID(); - // Check if the post should be displayed on this day of the week + // Check display days + $current_date = new DateTime('now', $this->wp_timezone); $display_days = get_field('post_kabelkrant_dagen', $post_id); - $today = date('N'); - - // Skip if today is not a display day - if (!empty($display_days) && !in_array($today, $display_days, true)) { + if (!empty($display_days) && !in_array($current_date->format('N'), $display_days, true)) { continue; } - // Skip if the post's expiration date has passed + // Check end date $end_date = get_field('post_kabelkrant_datum_uit', $post_id); if (!empty($end_date)) { $end_date = trim($end_date); - - $wp_timezone = new DateTimeZone(wp_timezone_string()); - $end_date_obj = DateTime::createFromFormat('Y-m-d H:i:s', $end_date, $wp_timezone); - - if ($end_date_obj) { - $end_timestamp = $end_date_obj->getTimestamp(); - $current_timestamp = current_time('timestamp'); - - if ($end_timestamp < $current_timestamp) { - continue; - } - } else { - // Date parsing failed, skip the post or handle the error + $end_date_obj = DateTime::createFromFormat('Y-m-d H:i:s', $end_date, $this->wp_timezone); + if ($end_date_obj && $current_date > $end_date_obj) { continue; } } - // Get the primary category image for the post + // Get content and images + $content = get_field('post_kabelkrant_content', $post_id); $slide_image = $this->get_primary_category_image($post_id); - // Check for content or extra images - $kabelkrant_content = get_field('post_kabelkrant_content', $post_id); - $extra_images = get_field('post_kabelkrant_extra_afbeeldingen', $post_id); - - if (!empty($kabelkrant_content)) { - // Split content by pages using "---" as a delimiter - $pages = preg_split('/\n*-{3,}\n*/', $kabelkrant_content); - - // Generate a slide for each page of content - foreach ($pages as $index => $page_content) { + if (!empty($content)) { + $pages = preg_split('/\n*-{3,}\n*/', $content); + foreach ($pages as $page_content) { $slides[] = [ - 'type' => 'text', - 'duration' => 20000, // 20 seconds per slide, adjust as needed - 'title' => get_the_title(), - 'body' => wpautop(trim($page_content)), - 'image' => !empty($slide_image) ? $slide_image : null, + 'type' => 'text', + 'duration' => self::SLIDE_DURATIONS['text'], + 'title' => get_the_title(), + 'body' => wpautop(trim($page_content)), + 'image' => $slide_image ?: null ]; } } - // Add extra images (if any) as separate slides, even if content is empty + // Add extra images + $extra_images = get_field('post_kabelkrant_extra_afbeeldingen', $post_id); if (!empty($extra_images)) { foreach ($extra_images as $image) { if (!empty($image['url'])) { $slides[] = [ - 'type' => 'image', - 'duration' => 7000, // 7 seconds per image, adjust as needed - 'url' => $image['url'], + 'type' => 'image', + 'duration' => self::SLIDE_DURATIONS['image'], + 'url' => $image['url'] ]; } } @@ -191,103 +215,77 @@ private function get_article_slides($block) return $slides; } - // Get the primary category image with a fallback + /** + * Haalt de primaire categorie afbeelding op + */ private function get_primary_category_image($post_id) { $primary_term_id = get_post_meta($post_id, '_yoast_wpseo_primary_category', true); - // Get image from the primary category if ($primary_term_id) { $term_image = get_field('teksttv_categorie_afbeelding', 'category_' . $primary_term_id); - if ($term_image) { + if (!empty($term_image['url'])) { return $term_image['url']; } } - // Fall back to post thumbnail if no primary category image return get_the_post_thumbnail_url($post_id, 'large'); } - // Generate an image slide from a block with day and date filtering + /** + * Genereert een image slide + */ private function get_image_slide($block) { - $current_timestamp = current_time('timestamp'); - $wp_timezone = new DateTimeZone(wp_timezone_string()); + $current_date = new DateTime('now', $this->wp_timezone); - // Check date range if 'datum_in' or 'datum_uit' is set + // Check date range if (!empty($block['datum_in'])) { - $start_date = trim($block['datum_in']); - $start_date_obj = DateTime::createFromFormat('d/m/Y', $start_date, $wp_timezone); - if ($start_date_obj && $current_timestamp < $start_date_obj->getTimestamp()) { - // Current date is before the start date + $start_date = DateTime::createFromFormat('d/m/Y', trim($block['datum_in']), $this->wp_timezone); + if ($start_date && $current_date < $start_date) { return null; } } if (!empty($block['datum_uit'])) { - $end_date = trim($block['datum_uit']); - $end_date_obj = DateTime::createFromFormat('d/m/Y', $end_date, $wp_timezone); - if ($end_date_obj && $current_timestamp > $end_date_obj->getTimestamp()) { - // Current date is after the end date + $end_date = DateTime::createFromFormat('d/m/Y', trim($block['datum_uit']), $this->wp_timezone); + if ($end_date && $current_date > $end_date) { return null; } } - // Check day filter if 'dagen' is set + // Check display days if (!empty($block['dagen'])) { - $today = date('N'); // 1 (Monday) to 7 (Sunday) - $allowed_days = $block['dagen']; // Array of strings ["1", "2", ..., "7"] - - if (!in_array((string)$today, $allowed_days, true)) { - // Today is not in the allowed days + $today = $current_date->format('N'); + if (!in_array($today, $block['dagen'], true)) { return null; } } - // If all checks pass, return the image slide if (!empty($block['afbeelding']) && !empty($block['afbeelding']['url'])) { return [ - 'type' => 'image', - 'duration' => intval($block['seconden']) * 1000, // Convert to milliseconds - 'url' => $block['afbeelding']['url'], + 'type' => 'image', + 'duration' => intval($block['seconden']) * 1000, + 'url' => $block['afbeelding']['url'] ]; } return null; } - // Retrieve active ad campaigns for display + /** + * Haalt actieve advertentie campagnes op + */ private function get_ad_campaigns() { $campaigns = []; if (function_exists('get_field')) { $all_campaigns = get_field('teksttv_reclame', 'option'); if ($all_campaigns) { - $current_timestamp = current_time('timestamp'); - $wp_timezone = new DateTimeZone(wp_timezone_string()); + $current_date = new DateTime('now', $this->wp_timezone); foreach ($all_campaigns as $campaign) { - // Get start and end timestamps for the campaign - $start_timestamp = 0; - if (!empty($campaign['campagne_datum_in'])) { - $start_date = trim($campaign['campagne_datum_in']); - $start_date_obj = DateTime::createFromFormat('d/m/Y', $start_date, $wp_timezone); - if ($start_date_obj) { - $start_timestamp = $start_date_obj->getTimestamp(); - } - } - - $end_timestamp = PHP_INT_MAX; - if (!empty($campaign['campagne_datum_uit'])) { - $end_date = trim($campaign['campagne_datum_uit']); - $end_date_obj = DateTime::createFromFormat('d/m/Y', $end_date, $wp_timezone); - if ($end_date_obj) { - $end_timestamp = $end_date_obj->getTimestamp(); - } - } - - // Check if the campaign is active - if ($current_timestamp >= $start_timestamp && $current_timestamp <= $end_timestamp) { + if ($this->is_campaign_active($campaign, $current_date)) { $campaigns[] = $campaign; } } @@ -296,42 +294,65 @@ private function get_ad_campaigns() return $campaigns; } - // Generate ad slides from campaigns + /** + * Controleert of een campagne actief is + */ + private function is_campaign_active($campaign, $current_date) + { + if (!empty($campaign['campagne_datum_in'])) { + $start_date = DateTime::createFromFormat('d/m/Y', trim($campaign['campagne_datum_in']), $this->wp_timezone); + if ($start_date && $current_date < $start_date) { + return false; + } + } + + if (!empty($campaign['campagne_datum_uit'])) { + $end_date = DateTime::createFromFormat('d/m/Y', trim($campaign['campagne_datum_uit']), $this->wp_timezone); + if ($end_date && $current_date > $end_date) { + return false; + } + } + + return true; + } + + /** + * Genereert advertentie slides + */ private function get_ad_slides($block, $campaigns) { $slides = []; - $group = $block['groep']; + $group = $block['groep']; - // Loop through each campaign and get the slides foreach ($campaigns as $campaign) { if (in_array($group, $campaign['campagne_groep'], true)) { foreach ($campaign['campagne_slides'] as $slide) { if (!empty($slide['url'])) { $slides[] = [ - 'type' => 'image', + 'type' => 'image', 'duration' => intval($campaign['campagne_seconden']) * 1000, - 'url' => $slide['url'], + 'url' => $slide['url'] ]; } } } } - // Add intro and outro images if available + // Add intro and outro images if (!empty($slides)) { if (!empty($block['afbeelding_in']) && !empty($block['afbeelding_in']['url'])) { array_unshift($slides, [ - 'type' => 'image', - 'duration' => 5000, // 5 seconds, adjust as needed - 'url' => $block['afbeelding_in']['url'], + 'type' => 'image', + 'duration' => self::SLIDE_DURATIONS['ad_transition'], + 'url' => $block['afbeelding_in']['url'] ]); } if (!empty($block['afbeelding_uit']) && !empty($block['afbeelding_uit']['url'])) { $slides[] = [ - 'type' => 'image', - 'duration' => 5000, // 5 seconds, adjust as needed - 'url' => $block['afbeelding_uit']['url'], + 'type' => 'image', + 'duration' => self::SLIDE_DURATIONS['ad_transition'], + 'url' => $block['afbeelding_uit']['url'] ]; } } @@ -339,42 +360,37 @@ private function get_ad_slides($block, $campaigns) return $slides; } - // Callback for the '/teksttv-ticker' endpoint - generates ticker messages + /** + * Haalt ticker berichten op + */ public function get_ticker_messages() { - $ticker_messages = []; + $messages = []; + $debug_info = $this->get_debug_info(); - // Check if ACF is active and 'teksttv_ticker' field exists if (function_exists('get_field')) { $ticker_content = get_field('teksttv_ticker', 'option'); - // If ticker content is available, process each item if ($ticker_content) { foreach ($ticker_content as $item) { switch ($item['acf_fc_layout']) { case 'ticker_nufm': $message = $this->get_current_fm_program(); if ($message) { - $ticker_messages[] = [ - 'message' => $message, - ]; + $messages[] = ['message' => $message]; } break; case 'ticker_straksfm': $message = $this->get_next_fm_program(); if ($message) { - $ticker_messages[] = [ - 'message' => $message, - ]; + $messages[] = ['message' => $message]; } break; case 'ticker_tekst': if (!empty($item['ticker_tekst_tekst'])) { - $ticker_messages[] = [ - 'message' => $item['ticker_tekst_tekst'], - ]; + $messages[] = ['message' => $item['ticker_tekst_tekst']]; } break; } @@ -382,23 +398,49 @@ public function get_ticker_messages() } } - return new WP_REST_Response($ticker_messages, 200); + return new WP_REST_Response([ + 'messages' => $messages, + '_debug' => $debug_info + ], 200); } - // Get the current FM program + /** + * Haalt het huidige FM programma op + */ private function get_current_fm_program() { $schedule = new BroadcastSchedule(); return 'Nu op Radio Rucphen: ' . $schedule->getCurrentRadioBroadcast()->getName(); } - // Get the next FM program + /** + * Haalt het volgende FM programma op + */ private function get_next_fm_program() { $schedule = new BroadcastSchedule(); return 'Straks op Radio Rucphen: ' . $schedule->getNextRadioBroadcast()->getName(); } + + /** + * Verzamelt debug informatie + */ + private function get_debug_info() + { + $current_date = new DateTime('now', $this->wp_timezone); + return [ + 'current_time' => $current_date->format('Y-m-d H:i:s'), + 'timezone' => [ + 'wp_timezone_string' => wp_timezone_string(), + 'wp_timezone_offset' => get_option('gmt_offset'), + 'php_timezone' => date_default_timezone_get(), + 'server_time' => date('Y-m-d H:i:s') + ] + ]; + } } -// Instantiate the API class -$teksttv_api = new TekstTVAPI(); +// Initialiseer de plugin +add_action('init', function () { + TekstTVAPI::get_instance(); +});