Skip to content

Commit

Permalink
feat: backup and restore (#288)
Browse files Browse the repository at this point in the history
  • Loading branch information
ellite authored Apr 26, 2024
1 parent 65cc376 commit 7b509d2
Show file tree
Hide file tree
Showing 31 changed files with 717 additions and 95 deletions.
2 changes: 2 additions & 0 deletions .tmp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ WORKDIR /var/www/html

# Update packages and install dependencies
RUN apk upgrade --no-cache && \
apk add --no-cache sqlite-dev libpng libpng-dev libjpeg-turbo libjpeg-turbo-dev freetype freetype-dev curl autoconf libgomp icu-dev nginx dcron tzdata imagemagick imagemagick-dev && \
apk add --no-cache sqlite-dev libpng libpng-dev libjpeg-turbo libjpeg-turbo-dev freetype freetype-dev curl autoconf libgomp icu-dev nginx dcron tzdata imagemagick imagemagick-dev libzip-dev && \
docker-php-ext-install pdo pdo_sqlite && \
docker-php-ext-enable pdo pdo_sqlite && \
docker-php-ext-configure gd --with-freetype --with-jpeg && \
docker-php-ext-install -j$(nproc) gd intl && \
docker-php-ext-install -j$(nproc) gd intl zip && \
apk add --no-cache --virtual .build-deps $PHPIZE_DEPS && \
pecl install imagick && \
docker-php-ext-enable imagick && \
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ See instructions to run Wallos below.
- intl
- openssl
- sqlite3
- zip

#### Docker

Expand Down
71 changes: 71 additions & 0 deletions endpoints/db/backup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}

function addFolderToZip($dir, $zipArchive, $zipdir = ''){
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
//Add the directory
if(!empty($zipdir)) $zipArchive->addEmptyDir($zipdir);
while (($file = readdir($dh)) !== false) {
// Skip '.' and '..'
if ($file == "." || $file == "..") {
continue;
}
//If it's a folder, run the function again!
if(is_dir($dir . $file)){
$newdir = $dir . $file . '/';
addFolderToZip($newdir, $zipArchive, $zipdir . $file . '/');
}else{
//Add the files
$zipArchive->addFile($dir . $file, $zipdir . $file);
}
}
}
} else {
die(json_encode([
"success" => false,
"message" => "Directory does not exist: $dir"
]));
}
}

$zip = new ZipArchive();
$filename = "backup_" . uniqid() . ".zip";
$zipname = "../../.tmp/" . $filename;

if ($zip->open($zipname, ZipArchive::CREATE)!==TRUE) {
die(json_encode([
"success" => false,
"message" => translate('cannot_open_zip', $i18n)
]));
}

addFolderToZip('../../db/', $zip);
addFolderToZip('../../images/uploads/', $zip);

$numberOfFilesAdded = $zip->numFiles;

if ($zip->close() === false) {
die(json_encode([
"success" => false,
"message" => "Failed to finalize the zip file"
]));
} else {
flush();
die(json_encode([
"success" => true,
"message" => "Zip file created successfully",
"numFiles" => $numberOfFilesAdded,
"file" => $filename
]));
}


?>
112 changes: 112 additions & 0 deletions endpoints/db/import.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php
require_once '../../includes/connect_endpoint.php';
session_start();

$result = $db->query("SELECT COUNT(*) as count FROM user");
$row = $result->fetchArray(SQLITE3_NUM);
if ($row[0] > 0) {
die(json_encode([
"success" => false,
"message" => "Denied"
]));
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_FILES['file'])) {
$file = $_FILES['file'];
$fileTmpName = $file['tmp_name'];
$fileError = $file['error'];

if ($fileError === 0) {
$fileDestination = '../../.tmp/restore.zip';
move_uploaded_file($fileTmpName, $fileDestination);

$zip = new ZipArchive();
if ($zip->open($fileDestination) === true) {
$zip->extractTo('../../.tmp/restore/');
$zip->close();
} else {
die(json_encode([
"success" => false,
"message" => "Failed to extract the uploaded file"
]));
}

if (file_exists('../../.tmp/restore/wallos.db')) {
if (file_exists('../../db/wallos.db')) {
unlink('../../db/wallos.db');
}
rename('../../.tmp/restore/wallos.db', '../../db/wallos.db');

if (file_exists('../../.tmp/restore/logos/')) {
$dir = '../../images/uploads/logos/';
$di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);

foreach ( $ri as $file ) {
if ( $file->isDir() ) {
rmdir($file->getPathname());
} else {
unlink($file->getPathname());
}
}

$dir = new RecursiveDirectoryIterator('../../.tmp/restore/logos/');
$ite = new RecursiveIteratorIterator($dir);
$allowedExtensions = ['png', 'jpg', 'jpeg', 'gif', 'webp'];

foreach ($ite as $filePath) {
if (in_array(pathinfo($filePath, PATHINFO_EXTENSION), $allowedExtensions)) {
$destination = str_replace('../../.tmp/restore/', '../../images/uploads/', $filePath);
$destinationDir = pathinfo($destination, PATHINFO_DIRNAME);

if (!is_dir($destinationDir)) {
mkdir($destinationDir, 0755, true);
}

copy($filePath, $destination);
}
}
}

$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator('../../.tmp', RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);

foreach ($files as $fileinfo) {
$removeFunction = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
$removeFunction($fileinfo->getRealPath());
}

echo json_encode([
"success" => true,
"message" => translate("success", $i18n)
]);
} else {
die(json_encode([
"success" => false,
"message" => "wallos.db does not exist in the backup file"
]));
}


} else {
echo json_encode([
"success" => false,
"message" => "Failed to upload file"
]);
}
} else {
echo json_encode([
"success" => false,
"message" => "No file uploaded"
]);
}
} else {
echo json_encode([
"success" => false,
"message" => "Invalid request method"
]);
}
?>
109 changes: 109 additions & 0 deletions endpoints/db/restore.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php
require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_FILES['file'])) {
$file = $_FILES['file'];
$fileTmpName = $file['tmp_name'];
$fileError = $file['error'];

if ($fileError === 0) {
$fileDestination = '../../.tmp/restore.zip';
move_uploaded_file($fileTmpName, $fileDestination);

$zip = new ZipArchive();
if ($zip->open($fileDestination) === true) {
$zip->extractTo('../../.tmp/restore/');
$zip->close();
} else {
die(json_encode([
"success" => false,
"message" => "Failed to extract the uploaded file"
]));
}

if (file_exists('../../.tmp/restore/wallos.db')) {
if (file_exists('../../db/wallos.db')) {
unlink('../../db/wallos.db');
}
rename('../../.tmp/restore/wallos.db', '../../db/wallos.db');

if (file_exists('../../.tmp/restore/logos/')) {
$dir = '../../images/uploads/logos/';
$di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);

foreach ( $ri as $file ) {
if ( $file->isDir() ) {
rmdir($file->getPathname());
} else {
unlink($file->getPathname());
}
}

$dir = new RecursiveDirectoryIterator('../../.tmp/restore/logos/');
$ite = new RecursiveIteratorIterator($dir);
$allowedExtensions = ['png', 'jpg', 'jpeg', 'gif', 'webp'];

foreach ($ite as $filePath) {
if (in_array(pathinfo($filePath, PATHINFO_EXTENSION), $allowedExtensions)) {
$destination = str_replace('../../.tmp/restore/', '../../images/uploads/', $filePath);
$destinationDir = pathinfo($destination, PATHINFO_DIRNAME);

if (!is_dir($destinationDir)) {
mkdir($destinationDir, 0755, true);
}

copy($filePath, $destination);
}
}
}

$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator('../../.tmp', RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);

foreach ($files as $fileinfo) {
$removeFunction = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
$removeFunction($fileinfo->getRealPath());
}

echo json_encode([
"success" => true,
"message" => translate("success", $i18n)
]);
} else {
die(json_encode([
"success" => false,
"message" => "wallos.db does not exist in the backup file"
]));
}


} else {
echo json_encode([
"success" => false,
"message" => "Failed to upload file"
]);
}
} else {
echo json_encode([
"success" => false,
"message" => "No file uploaded"
]);
}
} else {
echo json_encode([
"success" => false,
"message" => "Invalid request method"
]);
}
?>
48 changes: 0 additions & 48 deletions endpoints/subscriptions/export.php

This file was deleted.

6 changes: 6 additions & 0 deletions includes/checksession.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
$stmt->bindValue(':username', $username, SQLITE3_TEXT);
$result = $stmt->execute();
$userData = $result->fetchArray(SQLITE3_ASSOC);

if ($userData === false) {
header('Location: logout.php');
exit();
}

if ($userData['avatar'] == "") {
$userData['avatar'] = "0";
}
Expand Down
6 changes: 6 additions & 0 deletions includes/footer.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,11 @@
<div class="progress success"></div>
</div>

<?php
if (isset($db)) {
$db->close();
}
?>

</body>
</html>
Loading

0 comments on commit 7b509d2

Please sign in to comment.