Changeset 3382845
- Timestamp:
- 10/22/2025 05:48:19 PM (5 months ago)
- Location:
- digital-signage/trunk
- Files:
-
- 2 edited
-
digital-signage.php (modified) (5 diffs)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
digital-signage/trunk/digital-signage.php
r3290139 r3382845 3 3 Plugin Name: Digital Signage 4 4 Description: Adds a page that displays a digital signage gallery of images from your WordPress posts. 5 Version: 1.0. 15 Version: 1.0.2 6 6 Author: stankovski 7 7 Author URI: https://github.com/stankovski/ … … 75 75 } 76 76 77 // Get image URL with modern format support (WebP, AVIF, etc.) 78 function digsign_get_modern_image_url($post_id, $image_size) { 79 $thumb_id = get_post_thumbnail_id($post_id); 80 if (!$thumb_id) { 81 return false; 82 } 83 84 // Check if webp-uploads plugin is active and modern formats should be used 85 $use_modern_formats = is_plugin_active('webp-uploads/webp-uploads.php') || 86 is_plugin_active('performance-lab/performance-lab.php') || 87 function_exists('webp_uploads_get_image_output_format'); 88 89 if ($use_modern_formats) { 90 // Get attachment metadata to check for modern format sources 91 $metadata = wp_get_attachment_metadata($thumb_id); 92 if (!empty($metadata) && isset($metadata['sizes'][$image_size]['sources'])) { 93 $upload_dir = wp_upload_dir(); 94 $base_url = trailingslashit($upload_dir['baseurl']); 95 $file_dir = dirname($metadata['file']); 96 97 // Get the preferred modern format 98 $preferred_format = 'webp'; 99 if (function_exists('webp_uploads_get_image_output_format')) { 100 $preferred_format = webp_uploads_get_image_output_format(); 101 } 102 103 // Look for modern format in sources 104 $sources = $metadata['sizes'][$image_size]['sources']; 105 if (isset($sources['image/' . $preferred_format])) { 106 $modern_file = $sources['image/' . $preferred_format]['file']; 107 return $base_url . trailingslashit($file_dir) . $modern_file; 108 } 109 110 // Fallback: look for any WebP source if preferred format not found 111 if ($preferred_format !== 'webp' && isset($sources['image/webp'])) { 112 $webp_file = $sources['image/webp']['file']; 113 return $base_url . trailingslashit($file_dir) . $webp_file; 114 } 115 } 116 117 // Check if full-size image has modern format sources 118 if (!empty($metadata) && isset($metadata['sources'])) { 119 $upload_dir = wp_upload_dir(); 120 $base_url = trailingslashit($upload_dir['baseurl']); 121 $file_dir = dirname($metadata['file']); 122 123 $preferred_format = 'webp'; 124 if (function_exists('webp_uploads_get_image_output_format')) { 125 $preferred_format = webp_uploads_get_image_output_format(); 126 } 127 128 // Look for modern format in full-size sources 129 $sources = $metadata['sources']; 130 if (isset($sources['image/' . $preferred_format])) { 131 $modern_file = $sources['image/' . $preferred_format]['file']; 132 return $base_url . trailingslashit($file_dir) . $modern_file; 133 } 134 135 // Fallback: look for any WebP source if preferred format not found 136 if ($preferred_format !== 'webp' && isset($sources['image/webp'])) { 137 $webp_file = $sources['image/webp']['file']; 138 return $base_url . trailingslashit($file_dir) . $webp_file; 139 } 140 } 141 } 142 143 // Fallback to standard method 144 return get_the_post_thumbnail_url($post_id, $image_size); 145 } 146 77 147 // Register custom image size (do not hook to after_setup_theme) 78 148 function digsign_register_image_sizes() { … … 156 226 require_once plugin_dir_path(__FILE__) . 'settings.php'; 157 227 228 /** 229 * Collect media (slides or image URLs) for a given category. 230 * Options (array): 231 * - category_name (string) 232 * - image_size (string) image size name to request 233 * - include_html (bool) whether to fallback to post HTML content when no featured image 234 * - include_qr (bool) whether to generate QR codes for posts 235 * - structure (string) 'slides' for detailed slide objects or 'urls' for simple list of image URLs 236 * 237 * @return array 238 */ 239 function digsign_collect_media($options = []) { 240 // Performance timing instrumentation 241 $start_time = microtime(true); 242 $timings = []; 243 244 $defaults = [ 245 'category_name' => 'news', 246 'image_size' => 'digsign-gallery-thumb', 247 'include_html' => true, 248 'include_qr' => true, 249 'structure' => 'slides', // 'slides' or 'urls' 250 ]; 251 $opts = wp_parse_args($options, $defaults); 252 253 $args = [ 254 'category_name' => $opts['category_name'], 255 'posts_per_page' => -1, 256 'post_status' => 'publish', 257 ]; 258 259 $query_start = microtime(true); 260 $query = new WP_Query($args); 261 $timings['database_query'] = (microtime(true) - $query_start) * 1000; 262 263 $results = []; 264 $processed_posts = 0; 265 $qr_generation_time = 0; 266 $image_processing_time = 0; 267 268 if ($query->have_posts()) { 269 while ($query->have_posts()) { 270 $query->the_post(); 271 $post_id = get_the_ID(); 272 $thumb_id = get_post_thumbnail_id($post_id); 273 274 // Time QR code generation 275 $qr_start = microtime(true); 276 $qr_code_url = ($opts['include_qr']) ? digsign_generate_qrcode($post_id) : ''; 277 $qr_generation_time += (microtime(true) - $qr_start) * 1000; 278 279 if ($thumb_id) { 280 $img_start = microtime(true); 281 282 // PERFORMANCE FIX: Skip expensive synchronous image regeneration 283 // Instead, use existing image sizes or fallback gracefully 284 $meta = wp_get_attachment_metadata($thumb_id); 285 286 // Log when image size is missing (for debugging) 287 if (!isset($meta['sizes'][$opts['image_size']])) { 288 error_log("Digital Signage: Missing image size '{$opts['image_size']}' for attachment {$thumb_id}, using fallback"); 289 } 290 291 // Get image URL with modern format support (WebP if available) 292 // If the requested size doesn't exist, try fallback sizes 293 $img_url = digsign_get_modern_image_url($post_id, $opts['image_size']); 294 295 // Fallback to other sizes if the requested size is not available 296 if (!$img_url && !isset($meta['sizes'][$opts['image_size']])) { 297 $fallback_sizes = ['large', 'medium_large', 'medium', 'full']; 298 foreach ($fallback_sizes as $fallback_size) { 299 $img_url = digsign_get_modern_image_url($post_id, $fallback_size); 300 if ($img_url) { 301 error_log("Digital Signage: Used fallback size '{$fallback_size}' for post {$post_id}"); 302 break; 303 } 304 } 305 } 306 if ($img_url) { 307 if ($opts['structure'] === 'urls') { 308 $results[] = $img_url; // simple list 309 } else { 310 $results[] = [ 311 'type' => 'image', 312 'content' => $img_url, 313 'qrcode' => $qr_code_url, 314 'post_title' => get_the_title(), 315 'post_url' => get_permalink($post_id), 316 ]; 317 } 318 } 319 } elseif ($opts['include_html'] && $opts['structure'] !== 'urls') { 320 // Fallback to post content (only for slides structure) 321 $content = apply_filters('the_content', get_the_content()); 322 if (!empty($content)) { 323 $results[] = [ 324 'type' => 'html', 325 'content' => $content, 326 'title' => get_the_title(), 327 'qrcode' => $qr_code_url, 328 'post_url' => get_permalink($post_id), 329 ]; 330 } 331 332 $image_processing_time += (microtime(true) - $img_start) * 1000; 333 } 334 $processed_posts++; 335 } 336 wp_reset_postdata(); 337 } 338 339 // Performance logging 340 $total_time = (microtime(true) - $start_time) * 1000; 341 $timings['total_execution'] = $total_time; 342 $timings['processed_posts'] = $processed_posts; 343 $timings['qr_generation'] = $qr_generation_time; 344 $timings['image_processing'] = $image_processing_time; 345 $timings['results_count'] = count($results); 346 347 // Add debug info to results if WP_DEBUG is enabled 348 if (defined('WP_DEBUG') && WP_DEBUG) { 349 $results['_debug_timing'] = $timings; 350 } 351 352 return $results; 353 } 354 158 355 // REST API endpoint for gallery images 159 356 add_action('rest_api_init', function () { … … 161 358 'methods' => 'GET', 162 359 'callback' => function () { 163 $category_name = get_option('digsign_category_name', 'news'); 164 $width = intval(get_option('digsign_image_width', 1260)); 165 $height = intval(get_option('digsign_image_height', 940)); 166 $image_size = 'digsign-gallery-thumb'; 167 $refresh_interval = intval(get_option('digsign_refresh_interval', 10)); 168 $slide_delay = absint(get_option('digsign_slide_delay', 5)); 169 $enable_qrcodes = (bool)get_option('digsign_enable_qrcodes', true); 170 $layout_type = get_option('digsign_layout_type', 'fullscreen'); 171 172 $args = [ 360 $category_name = get_option('digsign_category_name', 'news'); 361 $refresh_interval = intval(get_option('digsign_refresh_interval', 10)); 362 $slide_delay = absint(get_option('digsign_slide_delay', 5)); 363 $enable_qrcodes = (bool)get_option('digsign_enable_qrcodes', true); 364 $layout_type = get_option('digsign_layout_type', 'fullscreen'); 365 $slides = digsign_collect_media([ 173 366 'category_name' => $category_name, 174 'posts_per_page' => -1, 175 'post_status' => 'publish', 176 ]; 177 $query = new WP_Query($args); 178 $slides = []; 179 if ($query->have_posts()) { 180 while ($query->have_posts()) { 181 $query->the_post(); 182 $post_id = get_the_ID(); 183 $thumb_id = get_post_thumbnail_id($post_id); 184 185 // Generate QR code only if enabled 186 $qr_code_url = $enable_qrcodes ? digsign_generate_qrcode($post_id) : ''; 187 188 if ($thumb_id) { 189 // Check if the custom size exists, generate if not 190 $meta = wp_get_attachment_metadata($thumb_id); 191 if (!isset($meta['sizes'][$image_size])) { 192 // Generate the image size on demand 193 require_once ABSPATH . 'wp-admin/includes/image.php'; 194 $fullsizepath = get_attached_file($thumb_id); 195 if ($fullsizepath && file_exists($fullsizepath)) { 196 $metadata = wp_generate_attachment_metadata($thumb_id, $fullsizepath); 197 if ($metadata && !is_wp_error($metadata)) { 198 wp_update_attachment_metadata($thumb_id, $metadata); 199 } 200 } 201 } 202 $img_url = get_the_post_thumbnail_url($post_id, $image_size); 203 if ($img_url) { 204 $slides[] = [ 205 'type' => 'image', 206 'content' => $img_url, 207 'qrcode' => $qr_code_url, 208 'post_title' => get_the_title(), 209 'post_url' => get_permalink($post_id) 210 ]; 211 } 212 } else { 213 // No featured image, use post content instead 214 $content = apply_filters('the_content', get_the_content()); 215 if (!empty($content)) { 216 $slides[] = [ 217 'type' => 'html', 218 'content' => $content, 219 'title' => get_the_title(), 220 'qrcode' => $qr_code_url, 221 'post_url' => get_permalink($post_id) 222 ]; 223 } 224 } 225 } 226 wp_reset_postdata(); 227 } 228 $layout_type = get_option('digsign_layout_type', 'fullscreen'); 229 367 'image_size' => 'digsign-gallery-thumb', 368 'include_html' => true, 369 'include_qr' => $enable_qrcodes, 370 'structure' => 'slides' 371 ]); 230 372 return rest_ensure_response([ 231 373 'slides' => $slides, … … 248 390 'callback' => function () { 249 391 $category_name = get_option('dsp_category_name', 'news'); 250 $width = intval(get_option('dsp_image_width', 1260)); 251 $height = intval(get_option('dsp_image_height', 940)); 252 $image_size = 'dsp-gallery-thumb'; 253 $args = [ 392 // Legacy endpoint only returns image URLs (no HTML, no QR codes) 393 $images = digsign_collect_media([ 254 394 'category_name' => $category_name, 255 'posts_per_page' => -1, 256 'post_status' => 'publish', 257 ]; 258 $query = new WP_Query($args); 259 $images = []; 260 if ($query->have_posts()) { 261 while ($query->have_posts()) { 262 $query->the_post(); 263 $post_id = get_the_ID(); 264 $thumb_id = get_post_thumbnail_id($post_id); 265 if ($thumb_id) { 266 // Check if the custom size exists, generate if not 267 $meta = wp_get_attachment_metadata($thumb_id); 268 if (!isset($meta['sizes'][$image_size])) { 269 // Generate the image size on demand 270 require_once ABSPATH . 'wp-admin/includes/image.php'; 271 $fullsizepath = get_attached_file($thumb_id); 272 if ($fullsizepath && file_exists($fullsizepath)) { 273 $metadata = wp_generate_attachment_metadata($thumb_id, $fullsizepath); 274 if ($metadata && !is_wp_error($metadata)) { 275 wp_update_attachment_metadata($thumb_id, $metadata); 276 } 277 } 278 } 279 $img_url = get_the_post_thumbnail_url($post_id, $image_size); 280 if ($img_url) { 281 $images[] = $img_url; 282 } 283 } 284 } 285 wp_reset_postdata(); 286 } 395 'image_size' => 'dsp-gallery-thumb', 396 'include_html' => false, 397 'include_qr' => false, 398 'structure' => 'urls' 399 ]); 287 400 return rest_ensure_response($images); 288 401 }, -
digital-signage/trunk/readme.txt
r3290143 r3382845 4 4 Requires at least: 5.0 5 5 Tested up to: 6.8 6 Stable tag: 1.0. 16 Stable tag: 1.0.2 7 7 Requires PHP: 7.0 8 8 License: MIT … … 41 41 == Screenshots == 42 42 43 1. Admin settings page44 2. Digital signage display showing rotating images43 1. Digital signage display showing rotating images 44 2. Admin settings page 45 45 46 46 == Changelog == 47 48 = 1.0.2 = 49 * Version bump 47 50 48 51 = 1.0.1 =
Note: See TracChangeset
for help on using the changeset viewer.