Some fixes

This commit is contained in:
mirivlad 2025-11-21 17:30:04 +08:00
parent 971b163367
commit 76d33237b2
7 changed files with 16 additions and 29 deletions

View File

@ -28,7 +28,7 @@ if (!$bookModel->userOwnsBook($book_id, $user_id)) {
redirect('books.php'); redirect('books.php');
} }
// Получаем информацию о книге перед удалением (для сообщения) // Получаем информацию о книге перед удалением
$book = $bookModel->findById($book_id); $book = $bookModel->findById($book_id);
if (!empty($book['cover_image'])) { if (!empty($book['cover_image'])) {
$cover_path = COVERS_PATH . $book['cover_image']; $cover_path = COVERS_PATH . $book['cover_image'];

View File

@ -2,8 +2,6 @@
require_once 'config/config.php'; require_once 'config/config.php';
require_login(); require_login();
// Подключаем функции для обложек
$user_id = $_SESSION['user_id']; $user_id = $_SESSION['user_id'];
$bookModel = new Book($pdo); $bookModel = new Book($pdo);
@ -99,8 +97,6 @@ $page_title = $is_edit ? "Редактирование книги" : "Созда
include 'views/header.php'; include 'views/header.php';
?> ?>
<!-- Остальная часть формы остается той же, но добавляем поле обложки -->
<form method="post" enctype="multipart/form-data"> <form method="post" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>"> <input type="hidden" name="csrf_token" value="<?= generate_csrf_token() ?>">
@ -147,7 +143,7 @@ include 'views/header.php';
placeholder="Номер по порядку в серии" placeholder="Номер по порядку в серии"
min="1" min="1"
style="width: 100%; margin-bottom: 1.5rem;"> style="width: 100%; margin-bottom: 1.5rem;">
<!-- ПОЛЕ ДЛЯ ОБЛОЖКИ --> <!-- Обложка -->
<div style="margin-bottom: 1.5rem;"> <div style="margin-bottom: 1.5rem;">
<label for="cover_image" style="display: block; margin-bottom: 0.5rem; font-weight: bold;"> <label for="cover_image" style="display: block; margin-bottom: 0.5rem; font-weight: bold;">
Обложка книги Обложка книги

View File

@ -117,7 +117,7 @@ include 'views/header.php';
</article> </article>
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>
<!-- Модальное окно для удаления всех книг --> <!-- Подтверждение удаления всех книг -->
<dialog id="deleteAllDialog" style="border-radius: 8px; padding: 20px; max-width: 500px; background-color: #fff;"> <dialog id="deleteAllDialog" style="border-radius: 8px; padding: 20px; max-width: 500px; background-color: #fff;">
<h3 style="margin-top: 0;">Удалить все книги?</h3> <h3 style="margin-top: 0;">Удалить все книги?</h3>
<p>Это действие удалит все ваши книги и все связанные с ними главы. Это действие нельзя отменить.</p> <p>Это действие удалит все ваши книги и все связанные с ними главы. Это действие нельзя отменить.</p>

View File

@ -28,7 +28,7 @@ if (!$chapterModel->userOwnsChapter($chapter_id, $user_id)) {
redirect('books.php'); redirect('books.php');
} }
// Получаем информацию о главе перед удалением (для редиректа)
$chapter = $chapterModel->findById($chapter_id); $chapter = $chapterModel->findById($chapter_id);
$book_id = $chapter['book_id']; $book_id = $chapter['book_id'];
@ -39,6 +39,5 @@ if ($chapterModel->delete($chapter_id)) {
$_SESSION['error'] = "Ошибка при удалении главы"; $_SESSION['error'] = "Ошибка при удалении главы";
} }
// Редирект обратно к списку глав книги
redirect("chapters.php?book_id=$book_id"); redirect("chapters.php?book_id=$book_id");
?> ?>

View File

@ -23,7 +23,6 @@ if ($chapter_id) {
$is_edit = true; $is_edit = true;
} }
// Проверяем, что book_id указан и пользователь имеет доступ к книге
if (!$book_id) { if (!$book_id) {
$_SESSION['error'] = "Не указана книга"; $_SESSION['error'] = "Не указана книга";
redirect('books.php'); redirect('books.php');
@ -47,8 +46,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Обработка автосохранения // Обработка автосохранения
if (isset($_POST['autosave']) && $_POST['autosave'] === 'true') { if (isset($_POST['autosave']) && $_POST['autosave'] === 'true') {
// Автосохранение работает только для существующих глав // Автосохранение работает только для существующих глав
// Если это не редактирование, игнорируем автосохранение
if (!$is_edit) { if (!$is_edit) {
// Если это не редактирование, игнорируем автосохранение
header('Content-Type: application/json'); header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'Автосохранение недоступно для новых глав']); echo json_encode(['success' => false, 'message' => 'Автосохранение недоступно для новых глав']);
exit; exit;
@ -200,7 +200,6 @@ include 'views/header.php';
</div> </div>
</form> </form>
<!-- Основные кнопки формы - Сохранить, Отмена и Предпросмотр -->
<div class="button-group"> <div class="button-group">
<button type="submit" form="main-form" class="contrast"> <button type="submit" form="main-form" class="contrast">
<?= $is_edit ? '💾 Сохранить изменения' : '📝 Создать главу' ?> <?= $is_edit ? '💾 Сохранить изменения' : '📝 Создать главу' ?>
@ -215,13 +214,12 @@ include 'views/header.php';
</button> </button>
</div> </div>
<!-- Скрытая форма для предпросмотра --> <!-- Форма для предпросмотра -->
<form method="post" action="preview.php" target="_blank" id="preview-form" style="display: none;"> <form method="post" action="preview.php" target="_blank" id="preview-form" style="display: none;">
<input type="hidden" name="content" id="preview-content"> <input type="hidden" name="content" id="preview-content">
<input type="hidden" name="title" id="preview-title" value="<?= e($chapter['title'] ?? 'Новая глава') ?>"> <input type="hidden" name="title" id="preview-title" value="<?= e($chapter['title'] ?? 'Новая глава') ?>">
</form> </form>
<!-- Дополнительные кнопки (вне основной формы) -->
<?php if ($is_edit): ?> <?php if ($is_edit): ?>
<div class="button-group"> <div class="button-group">
<a href="chapter_edit.php?book_id=<?= $book_id ?>" role="button"> <a href="chapter_edit.php?book_id=<?= $book_id ?>" role="button">

View File

@ -13,7 +13,7 @@ if (!$book_id) {
$bookModel = new Book($pdo); $bookModel = new Book($pdo);
$chapterModel = new Chapter($pdo); $chapterModel = new Chapter($pdo);
// Проверяем права доступа к книге
if (!$bookModel->userOwnsBook($book_id, $user_id)) { if (!$bookModel->userOwnsBook($book_id, $user_id)) {
$_SESSION['error'] = "У вас нет доступа к этой книге"; $_SESSION['error'] = "У вас нет доступа к этой книге";
redirect('books.php'); redirect('books.php');

View File

@ -55,10 +55,7 @@ if ($book) {
} }
$author_name = $author_info['display_name'] ?? $author_info['username'] ?? 'Неизвестный автор'; $author_name = $author_info['display_name'] ?? $author_info['username'] ?? 'Неизвестный автор';
// Функция для очистки имени файла
// function cleanFilename($filename) {
// return preg_replace('/[^a-zA-Z0-9_\-]/', '_', $filename);
// }
// Функция для преобразования Markdown в чистый текст с форматированием абзацев // Функция для преобразования Markdown в чистый текст с форматированием абзацев
function markdownToPlainText($markdown) { function markdownToPlainText($markdown) {
@ -98,7 +95,7 @@ function markdownToPlainText($markdown) {
return $text; return $text;
} }
// Улучшенная функция для разбивки Markdown на абзацы с сохранением структуры // Функция для разбивки Markdown на абзацы с сохранением структуры
function markdownToParagraphs($markdown) { function markdownToParagraphs($markdown) {
// Нормализуем переносы строк // Нормализуем переносы строк
$text = str_replace(["\r\n", "\r"], "\n", $markdown); $text = str_replace(["\r\n", "\r"], "\n", $markdown);
@ -239,9 +236,6 @@ switch ($format) {
case 'docx': case 'docx':
exportDOCX($book, $chapters, $is_public, $author_name); exportDOCX($book, $chapters, $is_public, $author_name);
break; break;
case 'odt':
exportODT($book, $chapters, $is_public, $author_name);
break;
case 'html': case 'html':
exportHTML($book, $chapters, $is_public, $author_name); exportHTML($book, $chapters, $is_public, $author_name);
break; break;
@ -317,7 +311,7 @@ function exportPDF($book, $chapters, $is_public, $author_name) {
$pdf->Ln(10); $pdf->Ln(10);
} }
// Интерактивное оглавление - СОЗДАЕМ ССЫЛКИ // Интерактивное оглавление
$chapterLinks = []; $chapterLinks = [];
if (!empty($chapters)) { if (!empty($chapters)) {
$pdf->SetFont('dejavusans', 'B', 14); $pdf->SetFont('dejavusans', 'B', 14);
@ -433,7 +427,7 @@ function exportDOCX($book, $chapters, $is_public, $author_name) {
foreach ($chapters as $index => $chapter) { foreach ($chapters as $index => $chapter) {
$chapter_number = $index + 1; $chapter_number = $index + 1;
// Создаем гиперссылку на заголовок главы - ИСПРАВЛЕННЫЙ СИНТАКСИС // Создаем гиперссылку на заголовок главы
$section->addLink("chapter_{$chapter['id']}", "{$chapter_number}. {$chapter['title']}", null, null, true); $section->addLink("chapter_{$chapter['id']}", "{$chapter_number}. {$chapter['title']}", null, null, true);
$section->addTextBreak(1); $section->addTextBreak(1);
} }
@ -443,9 +437,9 @@ function exportDOCX($book, $chapters, $is_public, $author_name) {
// Разделитель // Разделитель
$section->addPageBreak(); $section->addPageBreak();
// Главы с закладками - ДОБАВЛЯЕМ ПРАВИЛЬНЫЕ ЗАКЛАДКИ // Главы с закладками
foreach ($chapters as $index => $chapter) { foreach ($chapters as $index => $chapter) {
// Добавляем закладку для главы ПЕРЕД заголовком // Добавляем закладку для главы
$section->addBookmark("chapter_{$chapter['id']}"); $section->addBookmark("chapter_{$chapter['id']}");
// Заголовок главы // Заголовок главы
@ -588,7 +582,7 @@ function exportHTML($book, $chapters, $is_public, $author_name) {
font-size: 12px; font-size: 12px;
color: #666; color: #666;
} }
/* Улучшаем отображение абзацев */ /* Отображение абзацев */
.chapter-content p { .chapter-content p {
margin-bottom: 1em; margin-bottom: 1em;
text-align: justify; text-align: justify;
@ -720,7 +714,7 @@ function exportTXT($book, $chapters, $is_public, $author_name) {
if (!empty($book['description'])) { if (!empty($book['description'])) {
$content .= "ОПИСАНИЕ:\n"; $content .= "ОПИСАНИЕ:\n";
// Увеличиваем ширину до 144 символов (80 * 1.8) // Ширина до 144 символов
$content .= wordwrap($book['description'], 144) . "\n\n"; $content .= wordwrap($book['description'], 144) . "\n\n";
} }