306 lines
10 KiB
PHP
Executable File
306 lines
10 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* Plugin Name: KGV FAQ
|
|
* Description: FAQ-Verwaltung mit Fragen, Antworten, Kategorien, sauberem Backend und Shortcode-Ausgabe.
|
|
* Version: 1.0.2
|
|
* Author: Ronny Grobel
|
|
* Author URI: https://apex-project.de/
|
|
* Plugin URI: https://apex-project.de/
|
|
* Update URI: https://git.apex-project.de/Wordpress_Plugins/KGV-FAQ
|
|
* Gitea Plugin URI: https://git.apex-project.de/Wordpress_Plugins/KGV-FAQ
|
|
*/
|
|
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
final class KGV_FAQ_Plugin {
|
|
|
|
const VERSION = '1.0.0';
|
|
const POST_TYPE = 'kgv_faq';
|
|
const TAXONOMY = 'kgv_faq_cat';
|
|
|
|
public function __construct() {
|
|
add_action('init', [$this, 'register_post_type']);
|
|
add_action('init', [$this, 'register_taxonomy']);
|
|
|
|
add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_assets']);
|
|
add_action('wp_enqueue_scripts', [$this, 'enqueue_front_assets']);
|
|
|
|
add_filter('manage_' . self::POST_TYPE . '_posts_columns', [$this, 'admin_columns']);
|
|
add_action('manage_' . self::POST_TYPE . '_posts_custom_column', [$this, 'admin_column_content'], 10, 2);
|
|
add_filter('manage_edit-' . self::POST_TYPE . '_sortable_columns', [$this, 'sortable_columns']);
|
|
|
|
add_shortcode('kgv_faq', [$this, 'faq_shortcode']);
|
|
|
|
register_activation_hook(__FILE__, [$this, 'activate']);
|
|
register_deactivation_hook(__FILE__, [$this, 'deactivate']);
|
|
}
|
|
|
|
public function activate() {
|
|
$this->register_post_type();
|
|
$this->register_taxonomy();
|
|
flush_rewrite_rules();
|
|
}
|
|
|
|
public function deactivate() {
|
|
flush_rewrite_rules();
|
|
}
|
|
|
|
public function register_post_type() {
|
|
register_post_type(self::POST_TYPE, [
|
|
'labels' => [
|
|
'name' => 'FAQ',
|
|
'singular_name' => 'FAQ',
|
|
'add_new' => 'Neu hinzufügen',
|
|
'add_new_item' => 'Neue Frage hinzufügen',
|
|
'edit_item' => 'Frage bearbeiten',
|
|
'new_item' => 'Neue Frage',
|
|
'view_item' => 'Frage ansehen',
|
|
'search_items' => 'Fragen durchsuchen',
|
|
'not_found' => 'Keine Fragen gefunden',
|
|
'not_found_in_trash' => 'Keine Fragen im Papierkorb gefunden',
|
|
'menu_name' => 'FAQ',
|
|
],
|
|
'public' => false,
|
|
'publicly_queryable' => false,
|
|
'exclude_from_search' => true,
|
|
'has_archive' => false,
|
|
'rewrite' => false,
|
|
'query_var' => false,
|
|
'show_ui' => true,
|
|
'show_in_menu' => true,
|
|
'show_in_nav_menus' => false,
|
|
'show_in_admin_bar' => true,
|
|
'show_in_rest' => true,
|
|
'menu_icon' => 'dashicons-editor-help',
|
|
'supports' => ['title', 'editor', 'excerpt', 'page-attributes'],
|
|
]);
|
|
}
|
|
|
|
public function register_taxonomy() {
|
|
register_taxonomy(self::TAXONOMY, [self::POST_TYPE], [
|
|
'labels' => [
|
|
'name' => 'FAQ-Kategorien',
|
|
'singular_name' => 'FAQ-Kategorie',
|
|
'search_items' => 'Kategorien durchsuchen',
|
|
'all_items' => 'Alle Kategorien',
|
|
'edit_item' => 'Kategorie bearbeiten',
|
|
'update_item' => 'Kategorie aktualisieren',
|
|
'add_new_item' => 'Neue Kategorie hinzufügen',
|
|
'new_item_name' => 'Neuer Kategoriename',
|
|
'menu_name' => 'Kategorien',
|
|
],
|
|
'public' => false,
|
|
'publicly_queryable' => false,
|
|
'hierarchical' => true,
|
|
'show_ui' => true,
|
|
'show_admin_column' => true,
|
|
'rewrite' => false,
|
|
'query_var' => false,
|
|
'show_in_rest' => true,
|
|
]);
|
|
}
|
|
|
|
public function enqueue_admin_assets($hook) {
|
|
global $post_type;
|
|
|
|
$allowed = ['post.php', 'post-new.php', 'edit.php', 'term.php', 'edit-tags.php'];
|
|
|
|
if (!in_array($hook, $allowed, true)) {
|
|
return;
|
|
}
|
|
|
|
if ($post_type !== self::POST_TYPE && (!isset($_GET['taxonomy']) || sanitize_key(wp_unslash($_GET['taxonomy'])) !== self::TAXONOMY)) {
|
|
return;
|
|
}
|
|
|
|
wp_enqueue_style(
|
|
'kgv-faq-admin',
|
|
plugin_dir_url(__FILE__) . 'assets/admin.css',
|
|
[],
|
|
self::VERSION
|
|
);
|
|
}
|
|
|
|
public function enqueue_front_assets() {
|
|
wp_enqueue_style(
|
|
'kgv-faq-front',
|
|
plugin_dir_url(__FILE__) . 'assets/front.css',
|
|
[],
|
|
self::VERSION
|
|
);
|
|
|
|
wp_enqueue_script(
|
|
'kgv-faq-front',
|
|
plugin_dir_url(__FILE__) . 'assets/front.js',
|
|
[],
|
|
self::VERSION,
|
|
true
|
|
);
|
|
}
|
|
|
|
public function admin_columns($columns) {
|
|
$new_columns = [];
|
|
|
|
foreach ($columns as $key => $label) {
|
|
if ($key === 'date') {
|
|
continue;
|
|
}
|
|
|
|
$new_columns[$key] = $label;
|
|
|
|
if ($key === 'title') {
|
|
$new_columns['kgv_faq_order'] = 'Reihenfolge';
|
|
$new_columns['kgv_faq_answer'] = 'Antwort';
|
|
}
|
|
}
|
|
|
|
$new_columns['date'] = 'Datum';
|
|
|
|
return $new_columns;
|
|
}
|
|
|
|
public function admin_column_content($column, $post_id) {
|
|
if ($column === 'kgv_faq_order') {
|
|
echo (int) get_post_field('menu_order', $post_id);
|
|
return;
|
|
}
|
|
|
|
if ($column === 'kgv_faq_answer') {
|
|
$content = get_post_field('post_content', $post_id);
|
|
$text = wp_strip_all_tags($content);
|
|
$text = mb_substr($text, 0, 120);
|
|
echo esc_html($text ? $text . '…' : '—');
|
|
}
|
|
}
|
|
|
|
public function sortable_columns($columns) {
|
|
$columns['kgv_faq_order'] = 'menu_order';
|
|
return $columns;
|
|
}
|
|
|
|
public function faq_shortcode($atts) {
|
|
$atts = shortcode_atts([
|
|
'category' => '',
|
|
'limit' => 100,
|
|
'show_filter' => '1',
|
|
'open_first' => '0',
|
|
'search' => '0',
|
|
], $atts, 'kgv_faq');
|
|
|
|
$selected_category = '';
|
|
|
|
if (!empty($_GET['faq_cat'])) {
|
|
$selected_category = sanitize_title(wp_unslash($_GET['faq_cat']));
|
|
} elseif (!empty($atts['category'])) {
|
|
$selected_category = sanitize_title($atts['category']);
|
|
}
|
|
|
|
$query_args = [
|
|
'post_type' => self::POST_TYPE,
|
|
'post_status' => 'publish',
|
|
'posts_per_page' => max(1, (int) $atts['limit']),
|
|
'orderby' => ['menu_order' => 'ASC', 'title' => 'ASC'],
|
|
'order' => 'ASC',
|
|
];
|
|
|
|
if ($selected_category) {
|
|
$query_args['tax_query'] = [[
|
|
'taxonomy' => self::TAXONOMY,
|
|
'field' => 'slug',
|
|
'terms' => $selected_category,
|
|
]];
|
|
}
|
|
|
|
$faq_query = new WP_Query($query_args);
|
|
$terms = get_terms([
|
|
'taxonomy' => self::TAXONOMY,
|
|
'hide_empty' => true,
|
|
]);
|
|
|
|
$uid = wp_unique_id('kgv-faq-');
|
|
$open_first = $atts['open_first'] === '1';
|
|
$show_search = $atts['search'] === '1';
|
|
|
|
ob_start();
|
|
|
|
echo '<div class="kgv-faq-wrapper" data-kgv-faq>';
|
|
|
|
if ($atts['show_filter'] === '1' && !is_wp_error($terms) && !empty($terms)) {
|
|
echo '<form class="kgv-faq-filter" method="get">';
|
|
|
|
foreach ($_GET as $key => $value) {
|
|
if ($key === 'faq_cat' || is_array($value)) {
|
|
continue;
|
|
}
|
|
|
|
echo '<input type="hidden" name="' . esc_attr($key) . '" value="' . esc_attr(wp_unslash($value)) . '">';
|
|
}
|
|
|
|
echo '<label for="' . esc_attr($uid . '-cat') . '"><strong>Kategorie:</strong></label> ';
|
|
echo '<select id="' . esc_attr($uid . '-cat') . '" name="faq_cat" onchange="this.form.submit()">';
|
|
echo '<option value="">Alle Fragen</option>';
|
|
|
|
foreach ($terms as $term) {
|
|
echo '<option value="' . esc_attr($term->slug) . '" ' . selected($selected_category, $term->slug, false) . '>';
|
|
echo esc_html($term->name);
|
|
echo '</option>';
|
|
}
|
|
|
|
echo '</select>';
|
|
echo '</form>';
|
|
}
|
|
|
|
if ($show_search) {
|
|
echo '<div class="kgv-faq-search-wrap">';
|
|
echo '<input type="search" class="kgv-faq-search" placeholder="Frage suchen …" aria-label="Frage suchen" data-kgv-faq-search>';
|
|
echo '</div>';
|
|
}
|
|
|
|
if ($faq_query->have_posts()) {
|
|
echo '<div class="kgv-faq-list">';
|
|
|
|
$index = 0;
|
|
|
|
while ($faq_query->have_posts()) {
|
|
$faq_query->the_post();
|
|
|
|
$faq_id = get_the_ID();
|
|
$button_id = $uid . '-button-' . $faq_id;
|
|
$panel_id = $uid . '-panel-' . $faq_id;
|
|
$is_open = $open_first && $index === 0;
|
|
|
|
echo '<article class="kgv-faq-item" data-kgv-faq-item>';
|
|
echo '<h3 class="kgv-faq-question">';
|
|
echo '<button type="button" class="kgv-faq-toggle' . ($is_open ? ' is-open' : '') . '" id="' . esc_attr($button_id) . '" aria-expanded="' . ($is_open ? 'true' : 'false') . '" aria-controls="' . esc_attr($panel_id) . '" data-kgv-faq-toggle>';
|
|
echo '<span>' . esc_html(get_the_title()) . '</span>';
|
|
echo '<span class="kgv-faq-icon" aria-hidden="true">+</span>';
|
|
echo '</button>';
|
|
echo '</h3>';
|
|
|
|
echo '<div class="kgv-faq-answer' . ($is_open ? ' is-open' : '') . '" id="' . esc_attr($panel_id) . '" role="region" aria-labelledby="' . esc_attr($button_id) . '"' . ($is_open ? '' : ' hidden') . '>';
|
|
echo '<div class="kgv-faq-answer__inner">';
|
|
echo wp_kses_post(wpautop(get_the_content()));
|
|
echo '</div>';
|
|
echo '</div>';
|
|
|
|
echo '</article>';
|
|
|
|
$index++;
|
|
}
|
|
|
|
echo '</div>';
|
|
wp_reset_postdata();
|
|
} else {
|
|
echo '<p>Keine Fragen gefunden.</p>';
|
|
}
|
|
|
|
echo '</div>';
|
|
|
|
return ob_get_clean();
|
|
}
|
|
}
|
|
|
|
new KGV_FAQ_Plugin();
|