BookStack/app/Exports/ZipExports/ZipExportReader.php
Dan Brown 74fce9640e
Some checks are pending
analyse-php / build (push) Waiting to run
lint-php / build (push) Waiting to run
test-migrations / build (8.1) (push) Waiting to run
test-migrations / build (8.2) (push) Waiting to run
test-migrations / build (8.3) (push) Waiting to run
test-php / build (8.1) (push) Waiting to run
test-php / build (8.2) (push) Waiting to run
test-php / build (8.3) (push) Waiting to run
ZIP Import: Added model+migration, and reader class
2024-11-02 17:17:34 +00:00

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;
}
}