This commit is contained in:
Sven Steinert
2026-05-13 12:19:42 +02:00
parent f4511b9213
commit 3ff9146a63
13 changed files with 499 additions and 76 deletions

View File

@@ -0,0 +1,125 @@
<?php
declare(strict_types=1);
namespace KbMarkdownImporter\Admin;
use KbMarkdownImporter\Repository\ProductRepository;
final class ProductsPage
{
public static function render(): void
{
if (! current_user_can('manage_kb_docs')) {
wp_die(esc_html__('You do not have permission to manage documentation products.', 'kb-markdown-importer'));
}
$repository = new ProductRepository();
self::handleActions($repository);
$products = $repository->allWithStats();
?>
<div class="wrap">
<h1><?php esc_html_e('Documentation Products', 'kb-markdown-importer'); ?></h1>
<p><?php esc_html_e('Manage imported products, repair their URL slugs, or remove a broken import from the frontend.', 'kb-markdown-importer'); ?></p>
<?php settings_errors('kb_markdown_products'); ?>
<table class="widefat striped">
<thead>
<tr>
<th><?php esc_html_e('Product', 'kb-markdown-importer'); ?></th>
<th><?php esc_html_e('Slug', 'kb-markdown-importer'); ?></th>
<th><?php esc_html_e('Versions', 'kb-markdown-importer'); ?></th>
<th><?php esc_html_e('Pages', 'kb-markdown-importer'); ?></th>
<th><?php esc_html_e('Actions', 'kb-markdown-importer'); ?></th>
</tr>
</thead>
<tbody>
<?php if (! $products) : ?>
<tr><td colspan="5"><?php esc_html_e('No products have been imported yet.', 'kb-markdown-importer'); ?></td></tr>
<?php endif; ?>
<?php foreach ($products as $item) : ?>
<?php
$term = $item['term'];
$formId = 'kb-markdown-product-' . (int) $term->term_id;
$versions = array_map(static fn (\WP_Term $version): string => $version->name, (array) $item['versions']);
?>
<tr>
<td>
<input form="<?php echo esc_attr($formId); ?>" class="regular-text" type="text" name="product_name" value="<?php echo esc_attr($term->name); ?>" aria-label="<?php esc_attr_e('Product name', 'kb-markdown-importer'); ?>">
</td>
<td>
<input form="<?php echo esc_attr($formId); ?>" class="regular-text" type="text" name="product_slug" value="<?php echo esc_attr($term->slug); ?>" aria-label="<?php esc_attr_e('Product slug', 'kb-markdown-importer'); ?>">
</td>
<td><?php echo esc_html($versions ? implode(', ', $versions) : __('No versions', 'kb-markdown-importer')); ?></td>
<td><?php echo esc_html((string) $item['page_count']); ?></td>
<td>
<form id="<?php echo esc_attr($formId); ?>" method="post" action="">
<?php wp_nonce_field('kb_markdown_update_product_' . $term->term_id); ?>
<input type="hidden" name="kb_markdown_product_action" value="update">
<input type="hidden" name="term_id" value="<?php echo esc_attr((string) $term->term_id); ?>">
<?php submit_button(__('Save', 'kb-markdown-importer'), 'secondary small', 'submit', false); ?>
</form>
<form method="post" action="" style="margin-top:8px;" onsubmit="return window.confirm('<?php echo esc_js(__('Move this product and its imported pages to the trash?', 'kb-markdown-importer')); ?>');">
<?php wp_nonce_field('kb_markdown_delete_product_' . $term->term_id); ?>
<input type="hidden" name="kb_markdown_product_action" value="delete">
<input type="hidden" name="term_id" value="<?php echo esc_attr((string) $term->term_id); ?>">
<label>
<input type="checkbox" name="trash_pages" value="1" checked>
<?php esc_html_e('Trash imported pages', 'kb-markdown-importer'); ?>
</label>
<?php submit_button(__('Delete product', 'kb-markdown-importer'), 'delete small', 'submit', false); ?>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php
}
private static function handleActions(ProductRepository $repository): void
{
$action = sanitize_key(wp_unslash((string) ($_POST['kb_markdown_product_action'] ?? '')));
if (! $action) {
return;
}
$termId = absint($_POST['term_id'] ?? 0);
if (! $termId) {
add_settings_error('kb_markdown_products', 'missing_term', __('Missing product ID.', 'kb-markdown-importer'), 'error');
return;
}
if ('update' === $action) {
check_admin_referer('kb_markdown_update_product_' . $termId);
$result = $repository->update(
$termId,
sanitize_text_field(wp_unslash((string) ($_POST['product_name'] ?? ''))),
sanitize_title(wp_unslash((string) ($_POST['product_slug'] ?? '')))
);
if (is_wp_error($result)) {
add_settings_error('kb_markdown_products', 'update_failed', $result->get_error_message(), 'error');
return;
}
add_settings_error('kb_markdown_products', 'updated', __('Product saved.', 'kb-markdown-importer'), 'success');
return;
}
if ('delete' === $action) {
check_admin_referer('kb_markdown_delete_product_' . $termId);
$trashPages = ! empty($_POST['trash_pages']);
$result = $repository->deleteProduct($termId, $trashPages);
if (is_wp_error($result)) {
add_settings_error('kb_markdown_products', 'delete_failed', $result->get_error_message(), 'error');
return;
}
add_settings_error('kb_markdown_products', 'deleted', __('Product deleted.', 'kb-markdown-importer'), 'success');
}
}
}