Merge branch 'issue-57' into 'develop'
feat: ✨ add faq feature from custom plugin #57 See merge request ldc-web/projets/reghalal!73
This commit is contained in:
commit
a6ebf6e3eb
7 changed files with 662 additions and 5 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -3,6 +3,7 @@ public/app/plugins/*
|
|||
!public/app/plugins/ldc-import-inco-products
|
||||
!public/app/plugins/.gitkeep
|
||||
public/app/mu-plugins/*/
|
||||
!public/app/mu-plugins/uwil-faq/
|
||||
public/app/themes/reghalal-theme/
|
||||
public/app/upgrade
|
||||
public/app/uploads/*
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
"uwil/admin-secure-wp": "^3.1",
|
||||
"uwil/import-social-networks-wp": "^2.0",
|
||||
"uwil/mesbr-wp": "^1.2",
|
||||
"uwil/reghalal-theme": "^1.5",
|
||||
"uwil/reghalal-theme": "^1.6",
|
||||
"vlucas/phpdotenv": "^5.5",
|
||||
"wpackagist-plugin/wordpress-seo": "^27.4",
|
||||
"wpackagist-plugin/wp-sitemap-page": "^1.9",
|
||||
|
|
|
|||
8
composer.lock
generated
8
composer.lock
generated
|
|
@ -2439,16 +2439,16 @@
|
|||
},
|
||||
{
|
||||
"name": "uwil/reghalal-theme",
|
||||
"version": "1.5.11",
|
||||
"version": "1.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "git@lab.s-web.fr:ldc-web/projets/reghalal-theme.git",
|
||||
"reference": "8b768d4df734fe2776f86f72dd046c774b070bc5"
|
||||
"reference": "f5b1fb01cdde6afe0a9bd010a45f6cbb8a03b698"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://lab.s-web.fr/api/v4/projects/143/packages/composer/archives/uwil/reghalal-theme.zip?sha=8b768d4df734fe2776f86f72dd046c774b070bc5",
|
||||
"reference": "8b768d4df734fe2776f86f72dd046c774b070bc5",
|
||||
"url": "https://lab.s-web.fr/api/v4/projects/143/packages/composer/archives/uwil/reghalal-theme.zip?sha=f5b1fb01cdde6afe0a9bd010a45f6cbb8a03b698",
|
||||
"reference": "f5b1fb01cdde6afe0a9bd010a45f6cbb8a03b698",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "wordpress-theme",
|
||||
|
|
|
|||
2
public/app/mu-plugins/uwil-faq.php
Normal file
2
public/app/mu-plugins/uwil-faq.php
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<?php
|
||||
require_once WPMU_PLUGIN_DIR . '/uwil-faq/index.php';
|
||||
238
public/app/mu-plugins/uwil-faq/index.php
Normal file
238
public/app/mu-plugins/uwil-faq/index.php
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
Plugin Name: UWIL FAQ
|
||||
Description: Plugin to manage topics, questions and responses
|
||||
Version: 1.0
|
||||
Author: UWIL
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/utils.php';
|
||||
|
||||
/**
|
||||
* Add foreign key constraints (dbDelta doesn't handle them).
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function uwil_add_foreign_keys(): void
|
||||
{
|
||||
global $wpdb;
|
||||
|
||||
$constraints = [
|
||||
[
|
||||
'table' => 'uwil_questions',
|
||||
'name' => 'fk_questions_topic',
|
||||
'sql' => "ALTER TABLE uwil_questions
|
||||
ADD CONSTRAINT fk_questions_topic
|
||||
FOREIGN KEY (topic_id) REFERENCES uwil_topics(id)
|
||||
ON DELETE CASCADE",
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($constraints as $constraint) {
|
||||
$exists = $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM information_schema.TABLE_CONSTRAINTS
|
||||
WHERE CONSTRAINT_SCHEMA = %s
|
||||
AND TABLE_NAME = %s
|
||||
AND CONSTRAINT_NAME = %s",
|
||||
DB_NAME,
|
||||
$constraint['table'],
|
||||
$constraint['name']
|
||||
));
|
||||
|
||||
if (!$exists) {
|
||||
$wpdb->query($constraint['sql']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create tables.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function uwil_faq_create_tables(): void
|
||||
{
|
||||
global $wpdb;
|
||||
$charset = $wpdb->get_charset_collate();
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
|
||||
dbDelta("CREATE TABLE uwil_topics (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
`order` INT NOT NULL DEFAULT 0
|
||||
) $charset;");
|
||||
dbDelta("CREATE TABLE uwil_questions (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
topic_id BIGINT UNSIGNED NOT NULL,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
contenu TEXT NOT NULL,
|
||||
`order` INT NOT NULL DEFAULT 0,
|
||||
KEY topic_id (topic_id)
|
||||
) $charset;");
|
||||
uwil_add_foreign_keys();
|
||||
}
|
||||
add_action('admin_init', function () {
|
||||
global $wpdb;
|
||||
$tables = ['uwil_topics', 'uwil_questions', 'uwil_responses'];
|
||||
foreach ($tables as $table) {
|
||||
if ($wpdb->get_var("SHOW TABLES LIKE '$table'") !== $table) {
|
||||
uwil_faq_create_tables();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Add button plugin in the admin.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function plugin_menu(): void
|
||||
{
|
||||
add_menu_page(
|
||||
'UWIL FAQ',
|
||||
'UWIL FAQ',
|
||||
'manage_options',
|
||||
'uwil-faq-topics',
|
||||
'renderTopics',
|
||||
'dashicons-editor-help',
|
||||
);
|
||||
add_submenu_page(
|
||||
'uwil-faq-topics',
|
||||
'Thématiques',
|
||||
'Thématiques',
|
||||
'manage_options',
|
||||
'uwil-faq-topics',
|
||||
'renderTopics',
|
||||
);
|
||||
add_submenu_page(
|
||||
'uwil-faq-topics',
|
||||
'Questions/Réponses',
|
||||
'Questions/Réponses',
|
||||
'manage_options',
|
||||
'uwil-faq-questions',
|
||||
'renderQuestions',
|
||||
);
|
||||
}
|
||||
add_action('admin_menu', 'plugin_menu');
|
||||
|
||||
/**
|
||||
* Add style resource.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function custom_style(): void
|
||||
{
|
||||
wp_register_style('uwil-faq', WPMU_PLUGIN_URL . '/uwil-faq/style.css');
|
||||
wp_enqueue_style('uwil-faq');
|
||||
}
|
||||
add_action('admin_init', 'custom_style');
|
||||
|
||||
/** LIMITS */
|
||||
define('UWIL_MIN_TOPIC', 3);
|
||||
define('UWIL_MAX_TOPIC', 6);
|
||||
define('UWIL_MIN_QUESTIONS_PER_TOPIC', 3);
|
||||
define('UWIL_MAX_QUESTIONS_PER_TOPIC', 8);
|
||||
|
||||
/**
|
||||
* Render FAQ topics page.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function renderTopics(): void
|
||||
{
|
||||
global $wpdb;
|
||||
uwil_render_crud([
|
||||
'table' => 'uwil_topics',
|
||||
'title' => 'Thématiques',
|
||||
'min_total' => UWIL_MIN_TOPIC,
|
||||
'max_total' => UWIL_MAX_TOPIC,
|
||||
'fields' => [
|
||||
[
|
||||
'name' => 'title',
|
||||
'label' => 'Titre',
|
||||
'type' => 'text',
|
||||
],
|
||||
],
|
||||
'columns' => [
|
||||
[
|
||||
'label' => 'Titre',
|
||||
'field' => 'title',
|
||||
],
|
||||
[
|
||||
'label' => 'Questions',
|
||||
'field' => 'id',
|
||||
'render' => function ($item) use ($wpdb) {
|
||||
$count = (int) $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM uwil_questions WHERE topic_id = %d",
|
||||
$item->id
|
||||
));
|
||||
$class = ($count < UWIL_MIN_QUESTIONS_PER_TOPIC || $count > UWIL_MAX_QUESTIONS_PER_TOPIC) ? 'uwil-count-warning' : 'uwil-count-ok';
|
||||
return '<span class="' . $class . '">' . $count . ' / ' . UWIL_MAX_QUESTIONS_PER_TOPIC . '</span>';
|
||||
},
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render FAQ questions page.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function renderQuestions(): void
|
||||
{
|
||||
global $wpdb;
|
||||
uwil_render_crud([
|
||||
'table' => 'uwil_questions',
|
||||
'title' => 'Questions',
|
||||
'parent_key' => 'topic_id',
|
||||
'min_per_parent' => UWIL_MIN_QUESTIONS_PER_TOPIC,
|
||||
'max_per_parent' => UWIL_MAX_QUESTIONS_PER_TOPIC,
|
||||
'filter' => [
|
||||
'key' => 'topic_id',
|
||||
'label' => 'Filtrer par thématique',
|
||||
'options' => fn() => $wpdb->get_results("SELECT id, title FROM uwil_topics ORDER BY `order`"),
|
||||
],
|
||||
'fields' => [
|
||||
[
|
||||
'name' => 'topic_id',
|
||||
'label' => 'Thématique',
|
||||
'type' => 'select',
|
||||
'options' => fn() => $wpdb->get_results("SELECT id, title FROM uwil_topics ORDER BY `order`"),
|
||||
],
|
||||
[
|
||||
'name' => 'title',
|
||||
'label' => 'Question',
|
||||
'type' => 'text',
|
||||
],
|
||||
[
|
||||
'name' => 'contenu',
|
||||
'label' => 'Réponse',
|
||||
'type' => 'wysiwyg',
|
||||
],
|
||||
],
|
||||
'columns' => [
|
||||
[
|
||||
'label' => 'Thématique',
|
||||
'field' => 'topic_id',
|
||||
'render' => function ($item) use ($wpdb) {
|
||||
return esc_html($wpdb->get_var($wpdb->prepare(
|
||||
"SELECT title FROM uwil_topics WHERE id = %d",
|
||||
$item->topic_id
|
||||
)));
|
||||
},
|
||||
],
|
||||
[
|
||||
'label' => 'Question',
|
||||
'field' => 'title',
|
||||
],
|
||||
[
|
||||
'label' => 'Réponse',
|
||||
'field' => 'contenu',
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
131
public/app/mu-plugins/uwil-faq/style.css
Normal file
131
public/app/mu-plugins/uwil-faq/style.css
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
:root {
|
||||
--faq-spacing: 15px;
|
||||
}
|
||||
|
||||
.uwil-faq {
|
||||
width: calc(100% - 20px);
|
||||
padding-right: 20px;
|
||||
padding-left: 0;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.uwil-faq-title {
|
||||
padding-bottom: 0px !important;
|
||||
margin-bottom: var(--faq-spacing) !important;
|
||||
}
|
||||
|
||||
.uwil-faq-cards {
|
||||
display: flex;
|
||||
gap: var(--faq-spacing);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.uwil-faq-card {
|
||||
background: #fff;
|
||||
border: 1px solid #c3c4c7;
|
||||
padding: 24px;
|
||||
text-align: center;
|
||||
min-width: 180px;
|
||||
flex: 1;
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.uwil-faq-card-count {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
margin: var(--faq-spacing) 0;
|
||||
}
|
||||
|
||||
.uwil-faq-card-label {
|
||||
color: #646970;
|
||||
margin-bottom: var(--faq-spacing);
|
||||
}
|
||||
|
||||
.uwil-faq-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: start;
|
||||
align-items: start;
|
||||
gap: var(--faq-spacing);
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1100px) {
|
||||
.uwil-faq-content {
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
.uwil-faq-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: start;
|
||||
align-items: stretch;
|
||||
width: 100%;
|
||||
gap: var(--faq-spacing);
|
||||
}
|
||||
|
||||
.uwil-faq-form {
|
||||
padding-bottom: var(--faq-spacing);
|
||||
border-bottom: 1px solid #c3c4c7;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: start;
|
||||
align-items: stretch;
|
||||
gap: var(--faq-spacing);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.uwil-faq-form select {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1100px) {
|
||||
.uwil-faq-form {
|
||||
padding-bottom: 0px;
|
||||
padding-right: var(--faq-spacing);
|
||||
border-bottom: 0;
|
||||
border-right: 1px solid #c3c4c7;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.uwil-faq-form > * {
|
||||
width: 25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.uwil-faq-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: stretch;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.uwil-faq-actions {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: stretch;
|
||||
gap: var(--faq-spacing);
|
||||
}
|
||||
|
||||
.uwil-faq-actions > * {
|
||||
width: inherit;
|
||||
margin: 0 !important;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.uwil-count-ok {
|
||||
color: #00a32a;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.uwil-count-warning {
|
||||
color: #d63638;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.uwil-faq-border-0 {
|
||||
border: 0 !important;
|
||||
}
|
||||
285
public/app/mu-plugins/uwil-faq/utils.php
Normal file
285
public/app/mu-plugins/uwil-faq/utils.php
Normal file
|
|
@ -0,0 +1,285 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* CRUD order.
|
||||
*
|
||||
* @param string $table Name of the table.
|
||||
* @param integer $id Target id to move.
|
||||
* @param string $direction Direction to move target element.
|
||||
* @param string|null $parent_key Relation parent key.
|
||||
* @return void
|
||||
*/
|
||||
function uwil_move_item(string $table, int $id, string $direction, ?string $parent_key = null): void
|
||||
{
|
||||
global $wpdb;
|
||||
|
||||
$current = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table WHERE id = %d", $id));
|
||||
if (!$current) return;
|
||||
|
||||
$operator = $direction === 'up' ? '<' : '>';
|
||||
$order = $direction === 'up' ? 'DESC' : 'ASC';
|
||||
|
||||
$where = "`order` $operator %d";
|
||||
$params = [$current->order];
|
||||
|
||||
if ($parent_key) {
|
||||
$where .= " AND $parent_key = %d";
|
||||
$params[] = $current->{$parent_key};
|
||||
}
|
||||
|
||||
$neighbor = $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT * FROM $table WHERE $where ORDER BY `order` $order LIMIT 1",
|
||||
...$params
|
||||
));
|
||||
|
||||
if ($neighbor) {
|
||||
$wpdb->update($table, ['order' => $neighbor->order], ['id' => $current->id]);
|
||||
$wpdb->update($table, ['order' => $current->order], ['id' => $neighbor->id]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CRUD generic.
|
||||
*
|
||||
* @param array $config {
|
||||
* string table Name of the table.
|
||||
* string title Title of the page.
|
||||
* array fields List of fields in formulary.
|
||||
* array columns Columns to display in the table.
|
||||
* string parent_key Name of the relationship column (optionnal).
|
||||
* }
|
||||
*/
|
||||
function uwil_render_crud(array $config): void
|
||||
{
|
||||
global $wpdb;
|
||||
$table = $config['table'];
|
||||
$parent_key = $config['parent_key'] ?? null;
|
||||
$min_per_parent = $config['min_per_parent'] ?? null;
|
||||
$max_per_parent = $config['max_per_parent'] ?? null;
|
||||
$min_total = $config['min_total'] ?? null;
|
||||
$max_total = $config['max_total'] ?? null;
|
||||
$filter = $config['filter'] ?? null;
|
||||
|
||||
// Delete action.
|
||||
if (isset($_GET['delete']) && check_admin_referer('uwil_delete_' . $_GET['delete'])) {
|
||||
$id = (int) $_GET['delete'];
|
||||
$item = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table WHERE id = %d", $id));
|
||||
|
||||
$can_delete = true;
|
||||
|
||||
if ($item && $parent_key && $min_per_parent !== null) {
|
||||
$count = (int) $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM $table WHERE $parent_key = %d",
|
||||
$item->{$parent_key}
|
||||
));
|
||||
if ($count <= $min_per_parent) {
|
||||
$can_delete = false;
|
||||
echo '<div class="error"><p>Suppression impossible : minimum de ' . esc_html($min_per_parent) . ' élément(s) requis.</p></div>';
|
||||
}
|
||||
}
|
||||
|
||||
if ($can_delete && $item && $min_total !== null) {
|
||||
$count = (int) $wpdb->get_var("SELECT COUNT(*) FROM $table");
|
||||
if ($count <= $min_total) {
|
||||
$can_delete = false;
|
||||
echo '<div class="error"><p>Suppression impossible : minimum de ' . esc_html($min_total) . ' élément(s) requis au total.</p></div>';
|
||||
}
|
||||
}
|
||||
|
||||
if ($can_delete) {
|
||||
$wpdb->delete($table, ['id' => $id]);
|
||||
echo '<div class="updated"><p>Élément supprimé.</p></div>';
|
||||
}
|
||||
}
|
||||
|
||||
// Add/modification.
|
||||
if (isset($_POST['uwil_submit']) && check_admin_referer('uwil_form_' . $config['table'])) {
|
||||
$data = [];
|
||||
foreach ($config['fields'] as $field) {
|
||||
$value = wp_unslash($_POST[$field['name']] ?? '');
|
||||
$data[$field['name']] = $field['type'] === 'wysiwyg'
|
||||
? wp_kses_post($value)
|
||||
: sanitize_text_field($value);
|
||||
}
|
||||
|
||||
$is_new = empty($_POST['id']);
|
||||
|
||||
$can_save = true;
|
||||
|
||||
// Check max per parent before save.
|
||||
if ($is_new && $parent_key && $max_per_parent !== null && !empty($data[$parent_key])) {
|
||||
$count = (int) $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM $table WHERE $parent_key = %d",
|
||||
$data[$parent_key]
|
||||
));
|
||||
if ($count >= $max_per_parent) {
|
||||
$can_save = false;
|
||||
echo '<div class="error"><p>Ajout impossible : maximum de ' . esc_html($max_per_parent) . ' élément(s) atteint pour ce parent.</p></div>';
|
||||
}
|
||||
}
|
||||
|
||||
// Check max total before save.
|
||||
if ($can_save && $is_new && $max_total !== null) {
|
||||
$count = (int) $wpdb->get_var("SELECT COUNT(*) FROM $table");
|
||||
if ($count >= $max_total) {
|
||||
$can_save = false;
|
||||
echo '<div class="error"><p>Ajout impossible : maximum de ' . esc_html($max_total) . ' élément(s) atteint au total.</p></div>';
|
||||
}
|
||||
}
|
||||
|
||||
if ($can_save) {
|
||||
if (!$is_new) {
|
||||
$wpdb->update($table, $data, ['id' => (int) $_POST['id']]);
|
||||
echo '<div class="updated"><p>Élément modifié.</p></div>';
|
||||
} else {
|
||||
$where = '';
|
||||
if ($parent_key && !empty($data[$parent_key])) {
|
||||
$where = $wpdb->prepare(" WHERE $parent_key = %d", $data[$parent_key]);
|
||||
}
|
||||
$max_order = (int) $wpdb->get_var("SELECT MAX(`order`) FROM $table$where");
|
||||
$data['order'] = $max_order + 1;
|
||||
$wpdb->insert($table, $data);
|
||||
echo '<div class="updated"><p>Élément ajouté.</p></div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Order action.
|
||||
if (isset($_GET['move'], $_GET['id']) && check_admin_referer('uwil_move_' . $_GET['id'])) {
|
||||
uwil_move_item($table, (int) $_GET['id'], $_GET['move'], $parent_key);
|
||||
}
|
||||
|
||||
// Edit action.
|
||||
$edit_item = null;
|
||||
if (isset($_GET['edit'])) {
|
||||
$edit_item = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table WHERE id = %d", (int) $_GET['edit']));
|
||||
}
|
||||
|
||||
// Filter action.
|
||||
$filter_value = null;
|
||||
if ($filter && isset($_GET[$filter['key']]) && $_GET[$filter['key']] !== '') {
|
||||
$filter_value = (int) $_GET[$filter['key']];
|
||||
}
|
||||
|
||||
// List and order.
|
||||
$order_by = $parent_key ? "$parent_key ASC, `order` ASC" : "`order` ASC";
|
||||
if ($filter_value) {
|
||||
$items = $wpdb->get_results($wpdb->prepare(
|
||||
"SELECT * FROM $table WHERE {$filter['key']} = %d ORDER BY $order_by",
|
||||
$filter_value
|
||||
));
|
||||
} else {
|
||||
$items = $wpdb->get_results("SELECT * FROM $table ORDER BY $order_by");
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="wrap uwil-faq">
|
||||
<h1 class="uwil-faq-title"><?= esc_html($config['title']) ?></h1>
|
||||
<div class="uwil-faq-content">
|
||||
<!-- Formulary -->
|
||||
<form class="uwil-faq-form" method="post">
|
||||
<?php wp_nonce_field('uwil_form_' . $config['table']); ?>
|
||||
<input type="hidden" name="id" value="<?= esc_attr($edit_item->id ?? '') ?>">
|
||||
<?php foreach ($config['fields'] as $field): ?>
|
||||
<?php
|
||||
$value = $edit_item->{$field['name']} ?? '';
|
||||
$field_id = 'uwil_field_' . $field['name'];
|
||||
?>
|
||||
<?php if ($field['type'] === 'select'): ?>
|
||||
<div class="uwil-faq-field">
|
||||
<label for="<?= esc_attr($field_id) ?>"><?= esc_html($field['label']) ?></label>
|
||||
<select id="<?= esc_attr($field_id) ?>" name="<?= esc_attr($field['name']) ?>" required>
|
||||
<option value="" selected disabled>Sélectionner une valeur</option>
|
||||
<?php foreach ($field['options']() as $opt): ?>
|
||||
<option value="<?= esc_attr($opt->id) ?>" <?= selected($value, $opt->id, false) ?>>
|
||||
<?= esc_html($opt->title) ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<?php elseif ($field['type'] === 'wysiwyg'): ?>
|
||||
<div class="uwil-faq-field">
|
||||
<label for="<?= esc_attr($field_id) ?>"><?= esc_attr($field['label']) ?></label>
|
||||
<?php
|
||||
wp_editor($value, esc_attr($field_id), [
|
||||
'textarea_name' => $field['name'],
|
||||
'teeny' => true,
|
||||
'media_buttons' => false,
|
||||
'textarea_rows' => 6,
|
||||
'quicktags' => false,
|
||||
'tinymce' => [
|
||||
'toolbar1' => 'bold,italic,underline,link,unlink',
|
||||
'toolbar2' => '',
|
||||
],
|
||||
]);
|
||||
?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="uwil-faq-field">
|
||||
<label for="<?= esc_attr($field_id) ?>"><?= esc_attr($field['label']) ?></label>
|
||||
<input id="<?= esc_attr($field_id) ?>" type="text" name="<?= esc_attr($field['name']) ?>" value="<?= esc_attr($value) ?>" required>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
<div class="uwil-faq-actions">
|
||||
<?php if ($edit_item): ?>
|
||||
<a href="<?= esc_url(remove_query_arg('edit')) ?>" class="button button-secondary">
|
||||
Annuler
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<button type="submit" name="uwil_submit" class="button button-primary">
|
||||
<?= $edit_item ? 'Modifier' : 'Ajouter' ?>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="uwil-faq-list">
|
||||
<!-- Filter -->
|
||||
<?php if ($filter): ?>
|
||||
<form method="get" class="uwil-faq-form uwil-faq-border-0">
|
||||
<input type="hidden" name="page" value="<?= esc_attr($_GET['page']) ?>">
|
||||
<div class="uwil-faq-field">
|
||||
<label for="uwil_filter_<?= esc_attr($filter['key']) ?>"><?= esc_html($filter['label']) ?></label>
|
||||
<select id="uwil_filter_<?= esc_attr($filter['key']) ?>" name="<?= esc_attr($filter['key']) ?>" onchange="this.form.submit()">
|
||||
<option value="">Toutes les thématiques</option>
|
||||
<?php foreach ($filter['options']() as $opt): ?>
|
||||
<option value="<?= esc_attr($opt->id) ?>" <?= selected($filter_value, $opt->id, false) ?>>
|
||||
<?= esc_html($opt->title) ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
<!-- Listing elements -->
|
||||
<table class="widefat">
|
||||
<thead>
|
||||
<tr>
|
||||
<?php foreach ($config['columns'] as $col): ?>
|
||||
<th><?= esc_html($col['label']) ?></th>
|
||||
<?php endforeach; ?>
|
||||
<th>Ordre</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($items as $item): ?>
|
||||
<tr>
|
||||
<?php foreach ($config['columns'] as $col): ?>
|
||||
<td><?= isset($col['render']) ? $col['render']($item) : esc_html($item->{$col['field']}) ?></td>
|
||||
<?php endforeach; ?>
|
||||
<td><?= esc_html($item->order) ?></td>
|
||||
<td>
|
||||
<a href="<?= wp_nonce_url(add_query_arg(['move' => 'up', 'id' => $item->id]), 'uwil_move_' . $item->id) ?>">▲</a>
|
||||
<a href="<?= wp_nonce_url(add_query_arg(['move' => 'down', 'id' => $item->id]), 'uwil_move_' . $item->id) ?>">▼</a> |
|
||||
<a href="<?= add_query_arg(['edit' => $item->id]) ?>">Éditer</a> |
|
||||
<a href="<?= wp_nonce_url(add_query_arg(['delete' => $item->id]), 'uwil_delete_' . $item->id) ?>" onclick="return confirm('Supprimer cet élément ?');">Supprimer</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue