get_fixed_events() as $event_key => $event_data) { if (isset($event_data['start'], $event_data['end']) && $today >= $event_data['start'] && $today <= $event_data['end']) { if (get_option("fsp_fixed_{$event_key}", 'yes') === 'yes') { $active_events[] = $event_data; } } } foreach ($this->get_custom_events($today) as $event_data) { $active_events[] = $event_data; } return $active_events; } private function get_fixed_events() { $test_year = isset($_GET['fsp_test_date']) ? substr(sanitize_text_field($_GET['fsp_test_date']), 0, 4) : date('Y'); $year = is_numeric($test_year) ? $test_year : date('Y'); $easter_date = date('Y-m-d', easter_date($year)); return [ 'advent' => ['name' => 'Adventszeit', 'start' => "$year-12-01", 'end' => "$year-12-23", 'class' => 'festive-advent', 'effects' => ['snow']], 'christmas' => ['name' => 'Weihnachten', 'start' => "$year-12-24", 'end' => "$year-12-26", 'class' => 'festive-christmas', 'effects' => ['snow', 'music', 'star', 'santa']], // NEU: Santa-Animation 'newyear' => ['name' => 'Silvester', 'start' => "$year-12-31", 'end' => ($year + 1) . "-01-01", 'class' => 'festive-newyear', 'effects' => ['newyear_fireworks']], 'halloween' => ['name' => 'Halloween', 'start' => "$year-10-31", 'end' => "$year-10-31", 'class' => 'festive-halloween', 'effects' => ['spiders']], 'easter' => ['name' => 'Ostern', 'start' => date('Y-m-d', strtotime($easter_date . ' -1 day')), 'end' => date('Y-m-d', strtotime($easter_date)), 'class' => 'festive-easter', 'effects' => ['eggs']], ]; } private function get_custom_events($today) { $custom_events = get_option('fsp_events', []); $active_custom_events = []; $today_day_month = date('m-d', strtotime($today)); if (is_array($custom_events)) { foreach ($custom_events as $event) { if (empty($event['date']) || !is_array($event)) continue; $event_date = sanitize_text_field($event['date']); $date_obj = DateTime::createFromFormat('d-m', $event_date) ?: DateTime::createFromFormat('Y-m-d', $event_date); if ($date_obj && $date_obj->format('m-d') === $today_day_month) { $name = trim(($event['name'] ?? '') . ' ' . ($event['text'] ?? '')); $active_custom_events[] = [ 'name' => $name ?: 'Besonderer Tag!', 'class' => 'festive-birthday', 'effects' => ['balloons', 'confetti'] ]; } } } return $active_custom_events; } public function load_assets() { $active_events = $this->get_active_events(); if (empty($active_events)) return; $body_classes = []; $effects_to_load = []; foreach ($active_events as $event) { if (!empty($event['class'])) $body_classes[] = $event['class']; if (!empty($event['effects'])) $effects_to_load = array_merge($effects_to_load, $event['effects']); } add_filter('body_class', function($classes) use ($body_classes) { return array_merge($classes, array_unique($body_classes)); }); wp_enqueue_style('fsp-style', plugin_dir_url(__FILE__) . 'assets/css/festive.css', [], '3.4'); wp_enqueue_script('jquery'); wp_localize_script('jquery', 'fsp_vars', [ 'plugin_url' => plugin_dir_url(__FILE__) ]); if (in_array('confetti', $effects_to_load) || in_array('newyear_fireworks', $effects_to_load)) { wp_enqueue_script('fsp-confetti-lib', plugin_dir_url(__FILE__) . 'assets/js/canvas-confetti.min.js', [], '3.4', true); } foreach (array_unique($effects_to_load) as $effect) { switch ($effect) { case 'snow': wp_enqueue_script('fsp-snow', plugin_dir_url(__FILE__) . 'assets/js/snowstorm.js', [], '3.4', true); break; case 'confetti': wp_add_inline_script('fsp-confetti-lib', 'jQuery(document).ready(function($) { setTimeout(() => confetti({particleCount: 200, spread: 120, origin: { y: 0.6 } }), 1000); });'); break; case 'eggs': wp_enqueue_script('fsp-eggs', plugin_dir_url(__FILE__) . 'assets/js/easter-eggs.js', ['jquery'], '3.4', true); break; case 'spiders': wp_enqueue_script('fsp-spiders', plugin_dir_url(__FILE__) . 'assets/js/halloween-spiders.js', ['jquery'], '3.4', true); break; case 'balloons': wp_enqueue_script('fsp-balloons', plugin_dir_url(__FILE__) . 'assets/js/balloons.js', ['jquery'], '3.4', true); break; case 'star': wp_enqueue_script('fsp-star', plugin_dir_url(__FILE__) . 'assets/js/christmas-star.js', ['jquery'], '3.4', true); break; case 'santa': // NEU: Santa-Animation wp_enqueue_script('fsp-santa', plugin_dir_url(__FILE__) . 'assets/js/santa-sleigh.js', ['jquery'], '3.4', true); break; case 'newyear_fireworks': $this->add_newyear_script(); break; } } } private function add_newyear_script() { $script = ' jQuery(document).ready(function($) { if (!$("body").hasClass("festive-newyear")) { return; } if (typeof confetti === "undefined") { console.error("FSP: Konfetti-Bibliothek nicht gefunden."); return; } function runBigFireworks() { var count = 250; var defaults = { origin: { y: 0.7 }, zIndex: 999999, colors: ["#bb0000", "#ffffff", "#ff0000", "#ffbb00", "#ffee00", "#00ff00", "#0099ff", "#0000ff"] }; function fire(particleRatio, opts) { confetti(Object.assign({}, defaults, opts, { particleCount: Math.floor(count * particleRatio) })); } fire(0.25, { spread: 26, startVelocity: 55 }); fire(0.2, { spread: 60 }); fire(0.35, { spread: 100, decay: 0.91, scalar: 0.8 }); fire(0.1, { spread: 120, startVelocity: 25, decay: 0.92, scalar: 1.2 }); fire(0.1, { spread: 120, startVelocity: 45 }); var rainDefaults = { origin: { y: 0 }, angle: 90, drift: 0, gravity: 1.2, scalar: 1.2, zIndex: 999999 }; confetti(Object.assign({}, rainDefaults, { particleCount: 40, x: 0.1, colors: ["#ff0000", "#00ff00", "#0000ff", "#ffff00"] })); confetti(Object.assign({}, rainDefaults, { particleCount: 40, x: 0.5, colors: ["#bb0000", "#ffffff", "#ffbb00", "#ffee00"] })); confetti(Object.assign({}, rainDefaults, { particleCount: 40, x: 0.9, colors: ["#ff0000", "#00ff00", "#0000ff", "#ffff00"] })); } function createRocket(isLastRocket) { const startX = Math.random() * window.innerWidth; const $rocket = $("
").css({ position: "fixed", width: "6px", height: "25px", background: "linear-gradient(to top, #ff4500, #ffa500)", bottom: "-30px", left: startX + "px", zIndex: 999999, borderRadius: "50% 50% 0 0", boxShadow: "0 0 15px 5px rgba(255, 165, 0, 0.8)" }); $("body").append($rocket); $rocket.animate( { bottom: window.innerHeight * 0.8 }, { duration: 1800, easing: "linear", complete: function() { const x = startX / window.innerWidth; const y = 0.2; confetti({ particleCount: 75, spread: 100, origin: { x: x, y: y }, colors: ["#ff0000", "#ffa500", "#ffff00", "#ffffff"], gravity: 1.1, scalar: 1.0, startVelocity: 40 }); if (isLastRocket) { setTimeout(runBigFireworks, 500); } $(this).remove(); } } ); } function runNewYearShow() { const rocketCount = 5 + Math.floor(Math.random() * 4); for (let i = 0; i < rocketCount; i++) { const isLast = (i === rocketCount - 1); setTimeout(() => createRocket(isLast), i * 400); } } runNewYearShow(); setInterval(runNewYearShow, 12000); }); '; wp_add_inline_script('fsp-confetti-lib', $script); } public function add_admin_menu_page() { add_options_page('Festive Seasons Pro', 'Festive Seasons', 'manage_options', 'festive-seasons-pro', [$this, 'render_admin_page']); } public function register_settings() { register_setting('fsp_settings_group', 'fsp_events'); foreach (array_keys($this->get_fixed_events()) as $key) { register_setting('fsp_settings_group', "fsp_fixed_{$key}"); } register_setting('fsp_settings_group', 'fsp_enable_music'); } public function render_admin_page() { $events = get_option('fsp_events', []); ?>