mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-02-25 05:19:40 +08:00
103 lines
2.8 KiB
PHP
103 lines
2.8 KiB
PHP
![]() |
<?php
|
||
|
|
||
|
namespace BookStack\Exports\ZipExports;
|
||
|
|
||
|
use BookStack\Exceptions\ZipExportException;
|
||
|
use ZipArchive;
|
||
|
|
||
|
class ZipExportReader
|
||
|
{
|
||
|
protected ZipArchive $zip;
|
||
|
protected bool $open = false;
|
||
|
|
||
|
public function __construct(
|
||
|
protected string $zipPath,
|
||
|
) {
|
||
|
$this->zip = new ZipArchive();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @throws ZipExportException
|
||
|
*/
|
||
|
protected function open(): void
|
||
|
{
|
||
|
if ($this->open) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Validate file exists
|
||
|
if (!file_exists($this->zipPath) || !is_readable($this->zipPath)) {
|
||
|
throw new ZipExportException(trans('errors.import_zip_cant_read'));
|
||
|
}
|
||
|
|
||
|
// Validate file is valid zip
|
||
|
$opened = $this->zip->open($this->zipPath, ZipArchive::RDONLY);
|
||
|
if ($opened !== true) {
|
||
|
throw new ZipExportException(trans('errors.import_zip_cant_read'));
|
||
|
}
|
||
|
|
||
|
$this->open = true;
|
||
|
}
|
||
|
|
||
|
public function close(): void
|
||
|
{
|
||
|
if ($this->open) {
|
||
|
$this->zip->close();
|
||
|
$this->open = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @throws ZipExportException
|
||
|
*/
|
||
|
public function readData(): array
|
||
|
{
|
||
|
$this->open();
|
||
|
|
||
|
// Validate json data exists, including metadata
|
||
|
$jsonData = $this->zip->getFromName('data.json') ?: '';
|
||
|
$importData = json_decode($jsonData, true);
|
||
|
if (!$importData) {
|
||
|
throw new ZipExportException(trans('errors.import_zip_cant_decode_data'));
|
||
|
}
|
||
|
|
||
|
return $importData;
|
||
|
}
|
||
|
|
||
|
public function fileExists(string $fileName): bool
|
||
|
{
|
||
|
return $this->zip->statName("files/{$fileName}") !== false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @throws ZipExportException
|
||
|
* @returns array{name: string, book_count: int, chapter_count: int, page_count: int}
|
||
|
*/
|
||
|
public function getEntityInfo(): array
|
||
|
{
|
||
|
$data = $this->readData();
|
||
|
$info = ['name' => '', 'book_count' => 0, 'chapter_count' => 0, 'page_count' => 0];
|
||
|
|
||
|
if (isset($data['book'])) {
|
||
|
$info['name'] = $data['book']['name'] ?? '';
|
||
|
$info['book_count']++;
|
||
|
$chapters = $data['book']['chapters'] ?? [];
|
||
|
$pages = $data['book']['pages'] ?? [];
|
||
|
$info['chapter_count'] += count($chapters);
|
||
|
$info['page_count'] += count($pages);
|
||
|
foreach ($chapters as $chapter) {
|
||
|
$info['page_count'] += count($chapter['pages'] ?? []);
|
||
|
}
|
||
|
} elseif (isset($data['chapter'])) {
|
||
|
$info['name'] = $data['chapter']['name'] ?? '';
|
||
|
$info['chapter_count']++;
|
||
|
$info['page_count'] += count($data['chapter']['pages'] ?? []);
|
||
|
} elseif (isset($data['page'])) {
|
||
|
$info['name'] = $data['page']['name'] ?? '';
|
||
|
$info['page_count']++;
|
||
|
}
|
||
|
|
||
|
return $info;
|
||
|
}
|
||
|
}
|