diff --git a/multi-team-card.php b/multi-team-card.php new file mode 100644 index 0000000..1a27427 --- /dev/null +++ b/multi-team-card.php @@ -0,0 +1,376 @@ +tag_name)) { + $latest_version = ltrim($release_data->tag_name, 'v'); // Entfernt 'v' falls vorhanden + if (version_compare($latest_version, $current_version, '>')) { + add_action('admin_notices', function() use ($latest_version) { + echo '
+

⚠️ Neue Version von WP Multi Teamcard verfügbar: Version ' . esc_html($latest_version) . ' ist jetzt auf Gitea verfügbar. Hier klicken, um die neue Version herunterzuladen. ⚠️

+
'; + }); + } + } +} +add_action('admin_init', 'check_for_new_release'); + + +// CPT registrieren +function teamcard_register_post_type() { + register_post_type('teamcard', [ + 'labels' => [ + 'name' => 'Teammitglieder', + 'singular_name' => 'Teammitglied', + 'add_new' => 'Neues Teammitglied', + 'add_new_item' => 'Teammitglied hinzufügen', + 'edit_item' => 'Teammitglied bearbeiten', + ], + 'public' => true, + 'show_ui' => false, // Wir nutzen eine eigene Admin-Seite + 'show_in_menu' => false, + 'menu_icon' => 'dashicons-groups', + 'supports' => ['title'], + 'has_archive' => false, + 'show_in_admin_bar' => false, + ]); + + register_taxonomy('teamcard_kategorie', 'teamcard', [ + 'labels' => [ + 'name' => 'Kategorien', + 'singular_name' => 'Kategorie', + ], + 'hierarchical' => true, + 'public' => true, + 'show_admin_column' => true, + 'show_ui' => true, // Kategorien im Admin-Menü anzeigen + ]); +} +add_action('init', 'teamcard_register_post_type'); + +// Admin-Menü hinzufügen +function teamcard_add_admin_menu() { + add_menu_page( + 'Team-Cards verwalten', + 'Team-Cards', + 'manage_options', + 'teamcard_management', + 'teamcard_render_admin_page', + 'dashicons-groups', + 30 + ); +} +add_action('admin_menu', 'teamcard_add_admin_menu'); + +// Die Hauptverwaltungsseite mit Tabs +function teamcard_render_admin_page() { + $active_tab = isset($_GET['tab']) ? sanitize_key($_GET['tab']) : 'team_members'; + ?> +
+

Team-Cards verwalten

+ + + +
+ +
+
+ 'Bitte gib einen Namen ein.']); + } + + $max_order = 0; + $posts = get_posts(['post_type' => 'teamcard', 'posts_per_page' => 1, 'orderby' => 'menu_order', 'order' => 'DESC']); + if (!empty($posts)) { + $max_order = $posts[0]->menu_order; + } + + $post_id = wp_insert_post([ + 'post_type' => 'teamcard', + 'post_title' => $name, + 'post_status' => 'publish', + 'menu_order' => $max_order + 1 + ]); + + if ($post_id) { + update_post_meta($post_id, '_teamcard_funktion', $funktion); + update_post_meta($post_id, '_teamcard_zustaendigkeit', $zustaendigkeit); + update_post_meta($post_id, '_teamcard_card_type', $card_type); + if ($bild_id > 0) { + update_post_meta($post_id, '_teamcard_bild_id', $bild_id); + } + $bild_url = $bild_id ? wp_get_attachment_image_url($bild_id, 'thumbnail') : ''; + wp_send_json_success(['id' => $post_id, 'bild_url' => $bild_url]); + } else { + wp_send_json_error(['message' => 'Fehler beim Erstellen des Teammitglieds.']); + } + }); + + add_action('wp_ajax_update_teamcard', function() { + check_ajax_referer('teamcard_nonce', 'nonce'); + $post_id = intval($_POST['id']); + $field = sanitize_text_field($_POST['field']); + $value = sanitize_textarea_field($_POST['value']); // Textarea erlauben + + if ($field === 'title') { + wp_update_post(['ID' => $post_id, 'post_title' => $value]); + } else { + update_post_meta($post_id, '_teamcard_' . $field, $value); + } + wp_send_json_success(); + }); + + add_action('wp_ajax_delete_teamcard', function() { + check_ajax_referer('teamcard_nonce', 'nonce'); + $post_id = intval($_POST['id']); + if (wp_delete_post($post_id, true)) { + wp_send_json_success(); + } else { + wp_send_json_error(['message' => 'Fehler beim Löschen.']); + } + }); + + add_action('wp_ajax_update_teamcard_image', function() { + check_ajax_referer('teamcard_nonce', 'nonce'); + $post_id = intval($_POST['id']); + $bild_id = intval($_POST['bild_id']); + update_post_meta($post_id, '_teamcard_bild_id', $bild_id); + $bild_url = wp_get_attachment_image_url($bild_id, 'thumbnail'); + wp_send_json_success(['bild_url' => $bild_url]); + }); + + add_action('wp_ajax_update_teamcard_order', function() { + check_ajax_referer('teamcard_nonce', 'nonce'); + $order = $_POST['order']; // This is an array of IDs + foreach ($order as $position => $post_id) { + wp_update_post(['ID' => intval($post_id), 'menu_order' => $position]); + } + wp_send_json_success(); + }); +} +add_action('init', 'teamcard_ajax_handlers'); + +// Admin-Skripte und Styles laden +function teamcard_admin_scripts($hook) { + if ($hook !== 'toplevel_page_teamcard_management') return; + + wp_enqueue_media(); + wp_enqueue_script('jquery-ui-sortable'); + + wp_enqueue_style('teamcard-admin-style', plugin_dir_url(__FILE__) . 'assets/css/teamcard-admin.css', [], '2.1'); + wp_enqueue_script('teamcard-admin-script', plugin_dir_url(__FILE__) . 'assets/js/teamcard-admin.js', ['jquery', 'jquery-ui-sortable'], '2.1', true); + + wp_localize_script('teamcard-admin-script', 'teamcard_data', [ + 'ajax_url' => admin_url('admin-ajax.php'), + 'nonce' => wp_create_nonce('teamcard_nonce') + ]); +} +add_action('admin_enqueue_scripts', 'teamcard_admin_scripts'); + +// Frontend-Styles laden +function teamcard_frontend_styles() { + // Nur laden, wenn der Shortcode auf der Seite ist + global $post; + if (is_a($post, 'WP_Post') && has_shortcode($post->post_content, 'teamcards')) { + wp_enqueue_style('teamcard-frontend-style', plugin_dir_url(__FILE__) . 'assets/css/teamcard-frontend.css', [], '2.1'); + } +} +add_action('wp_enqueue_scripts', 'teamcard_frontend_styles'); + + +// Shortcode für die Frontend-Anzeige +function teamcard_shortcode($atts) { + $atts = shortcode_atts([ + 'kategorie' => '', + 'type' => get_option('teamcard_default_card_type', 'standard'), + 'columns' => get_option('teamcard_columns', 2), + ], $atts, 'teamcards'); + + $args = [ + 'post_type' => 'teamcard', + 'posts_per_page' => -1, + 'orderby' => 'menu_order', + 'order' => 'ASC', + ]; + + if (!empty($atts['kategorie'])) { + $args['tax_query'] = [[ + 'taxonomy' => 'teamcard_kategorie', + 'field' => 'slug', + 'terms' => sanitize_text_field($atts['kategorie']), + ]]; + } + + $query = new WP_Query($args); + if (!$query->have_posts()) { + return '

Keine Teammitglieder gefunden.

'; + } + + // Spaltenbreite für das Grid berechnen + $column_style = ''; + if ($atts['columns'] > 1) { + $column_width = (100 / $atts['columns']) - 2; // 2% für den gap + $column_style = "style='flex-basis: calc({$column_width}% - 20px);'"; + } else { + $column_style = "style='flex-basis: 100%;'"; + } + + + ob_start(); + echo '
'; + while ($query->have_posts()) { + $query->the_post(); + $post_id = get_the_ID(); + $meta = [ + 'funktion' => get_post_meta($post_id, '_teamcard_funktion', true), + 'zustaendigkeit' => get_post_meta($post_id, '_teamcard_zustaendigkeit', true), + 'bild_id' => get_post_meta($post_id, '_teamcard_bild_id', true), + 'card_type' => get_post_meta($post_id, '_teamcard_card_type', true), + ]; + $meta['bild_url'] = $meta['bild_id'] ? wp_get_attachment_url($meta['bild_id']) : ''; + + // Card-Typ aus dem Meta-Feld verwenden, falls vorhanden, sonst den aus dem Shortcode + $card_type_to_render = !empty($meta['card_type']) ? $meta['card_type'] : $atts['type']; + + // Sicherstellen, dass die Template-Datei existiert + $template_file = plugin_dir_path(__FILE__) . "templates/card-{$card_type_to_render}.php"; + if (file_exists($template_file)) { + include $template_file; + } else { + // Fallback auf Standard-Template, falls spezifisches nicht existiert + include plugin_dir_path(__FILE__) . 'templates/card-standard.php'; + } + } + echo '
'; + wp_reset_postdata(); + return ob_get_clean(); +} +add_shortcode('teamcards', 'teamcard_shortcode'); + +// Einstellungs-API registrieren +function teamcard_register_settings() { + register_setting('teamcard_settings_group', 'teamcard_default_card_type', ['sanitize_callback' => 'sanitize_text_field']); + register_setting('teamcard_settings_group', 'teamcard_columns', ['sanitize_callback' => 'absint']); + + add_settings_section( + 'teamcard_settings_section', + 'Anzeige-Einstellungen', + '__return_false', // Keine Beschreibung nötig + 'teamcard_settings' + ); + + add_settings_field( + 'teamcard_default_card_type', + 'Standard Card-Typ', + 'teamcard_default_card_type_callback', + 'teamcard_settings', + 'teamcard_settings_section' + ); + + add_settings_field( + 'teamcard_columns', + 'Anzahl der Spalten', + 'teamcard_columns_callback', + 'teamcard_settings', + 'teamcard_settings_section' + ); +} +add_action('admin_init', 'teamcard_register_settings'); + +function teamcard_default_card_type_callback() { + $default_card_type = get_option('teamcard_default_card_type', 'standard'); + ?> + +

Dieser Typ wird verwendet, wenn für ein Mitglied kein spezifischer Typ festgelegt ist.

+ + +

Anzahl der Spalten für die Teammitglieder-Anzeige (1-4).

+ 'teamcard', + 'posts_per_page' => -1, + 'post_status' => 'any', + ]); + + // Jeden Post und zugehörige Bilder löschen + foreach ($teamcards as $teamcard) { + // Bild aus der Mediathek löschen, falls vorhanden + $bild_id = get_post_meta($teamcard->ID, '_teamcard_bild_id', true); + if ($bild_id) { + wp_delete_attachment($bild_id, true); + } + // Post und Metadaten löschen + wp_delete_post($teamcard->ID, true); + } + + // Taxonomie 'teamcard_kategorie' und ihre Begriffe löschen + $terms = get_terms([ + 'taxonomy' => 'teamcard_kategorie', + 'hide_empty' => false, + ]); + + if (!is_wp_error($terms)) { + foreach ($terms as $term) { + wp_delete_term($term->term_id, 'teamcard_kategorie'); + } + } + + // Alle Metadaten löschen, die mit dem Plugin verknüpft sind + global $wpdb; + $wpdb->query("DELETE FROM $wpdb->postmeta WHERE meta_key LIKE '_teamcard_%'"); + + // Rewrite Rules zurücksetzen + flush_rewrite_rules(); +} + +// Funktion ausführen +delete_teamcard_data(); \ No newline at end of file