diff --git a/.tmp/.gitignore b/.tmp/.gitignore new file mode 100644 index 000000000..a3a0c8b5f --- /dev/null +++ b/.tmp/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index c3fa63fd2..2b3ae8064 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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 && \ diff --git a/README.md b/README.md index 93da5076d..e6353c984 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ See instructions to run Wallos below. - intl - openssl - sqlite3 + - zip #### Docker diff --git a/endpoints/db/backup.php b/endpoints/db/backup.php new file mode 100644 index 000000000..4a168fd24 --- /dev/null +++ b/endpoints/db/backup.php @@ -0,0 +1,68 @@ + 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(); +$zipname = "../../.tmp/backup.zip"; + +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 { + die(json_encode([ + "success" => true, + "message" => "Zip file created successfully", + "numFiles" => $numberOfFilesAdded + ])); +} + + +?> \ No newline at end of file diff --git a/endpoints/db/restore.php b/endpoints/db/restore.php new file mode 100644 index 000000000..ff66eb427 --- /dev/null +++ b/endpoints/db/restore.php @@ -0,0 +1,111 @@ + 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) { + // Handle the uploaded file here + // The uploaded file will be stored as restore.zip + $fileDestination = '../../.tmp/restore.zip'; + move_uploaded_file($fileTmpName, $fileDestination); + + // Unzip the uploaded file + $zip = new ZipArchive(); + if ($zip->open($fileDestination) === true) { + $zip->extractTo('../../.tmp/restore/'); + $zip->close(); + } + + // Check if wallos.db file exists in the restore folder + if (file_exists('../../.tmp/restore/wallos.db')) { + // Replace the wallos.db file in the db directory with the wallos.db file in the restore directory + if (file_exists('../../db/wallos.db')) { + unlink('../../db/wallos.db'); + } + rename('../../.tmp/restore/wallos.db', '../../db/wallos.db'); + + // Check if restore/logos/ directory exists + if (file_exists('../../.tmp/restore/logos/')) { + // Delete the files and folders in the uploaded logos directory + $dir = '../../images/uploads/logos/'; + + // Create recursive directory iterator + $di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS); + + // Create recursive iterator iterator in Child First Order + $ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST); + + // For each item in the recursive iterator + foreach ( $ri as $file ) { + // If the item is a directory + if ( $file->isDir() ) { + // Remove the directory + rmdir($file->getPathname()); + } else { + // If the item is a file + // Remove the file + unlink($file->getPathname()); + } + } + + // Copy the contents of restore/logos/ directory to the ../../images/uploads/logos/ directory + $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); + } + } + } + + echo json_encode([ + "success" => true, + "message" => "File uploaded and wallos.db exists" + ]); + } 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" + ]); +} +?> \ No newline at end of file diff --git a/endpoints/subscriptions/export.php b/endpoints/subscriptions/export.php deleted file mode 100644 index 2b8df91d0..000000000 --- a/endpoints/subscriptions/export.php +++ /dev/null @@ -1,48 +0,0 @@ - false, - "message" => translate('session_expired', $i18n) - ])); -} - -require_once '../../includes/getdbkeys.php'; - -$query = "SELECT * FROM subscriptions"; - -$result = $db->query($query); -if ($result) { - $subscriptions = array(); - while ($row = $result->fetchArray(SQLITE3_ASSOC)) { - // Map foreign keys to their corresponding values - $row['currency'] = $currencies[$row['currency_id']]; - $row['payment_method'] = $payment_methods[$row['payment_method_id']]; - $row['payer_user'] = $members[$row['payer_user_id']]; - $row['category'] = $categories[$row['category_id']]; - $row['cycle'] = $cycles[$row['cycle']]; - $row['frequency'] = $frequencies[$row['frequency']]; - - $subscriptions[] = $row; - } - - // Output JSON - $json = json_encode($subscriptions, JSON_PRETTY_PRINT); - - // Set headers for file download - header('Content-Type: application/json'); - header('Content-Disposition: attachment; filename="subscriptions.json"'); - header('Pragma: no-cache'); - header('Expires: 0'); - - // Output JSON for download - echo $json; -} else { - echo json_encode(array('error' => 'Failed to fetch subscriptions.')); -} - -?> \ No newline at end of file diff --git a/includes/footer.php b/includes/footer.php index b15b6186e..55c8038a0 100644 --- a/includes/footer.php +++ b/includes/footer.php @@ -24,5 +24,11 @@
+ close(); + } + ?> +