-
-
Notifications
You must be signed in to change notification settings - Fork 145
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: added custom payment methods (#173)
- Loading branch information
Showing
21 changed files
with
691 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
<?php | ||
error_reporting(E_ERROR | E_PARSE); | ||
require_once '../../includes/connect_endpoint.php'; | ||
require_once '../../includes/inputvalidation.php'; | ||
require_once '../../includes/getsettings.php'; | ||
|
||
session_start(); | ||
|
||
function sanitizeFilename($filename) { | ||
$filename = preg_replace("/[^a-zA-Z0-9\s]/", "", $filename); | ||
$filename = str_replace(" ", "-", $filename); | ||
return $filename; | ||
} | ||
|
||
function getLogoFromUrl($url, $uploadDir, $name) { | ||
|
||
$ch = curl_init($url); | ||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | ||
|
||
$imageData = curl_exec($ch); | ||
|
||
if ($imageData !== false) { | ||
$timestamp = time(); | ||
$fileName = $timestamp . '-payments-' . sanitizeFilename($name) . '.png'; | ||
$uploadDir = '../../images/uploads/logos/'; | ||
$uploadFile = $uploadDir . $fileName; | ||
|
||
if (saveLogo($imageData, $uploadFile, $name)) { | ||
return $fileName; | ||
} else { | ||
echo translate('error_fetching_image', $i18n) . ": " . curl_error($ch); | ||
return ""; | ||
} | ||
|
||
curl_close($ch); | ||
} else { | ||
echo translate('error_fetching_image', $i18n) . ": " . curl_error($ch); | ||
return ""; | ||
} | ||
} | ||
|
||
function saveLogo($imageData, $uploadFile, $name) { | ||
$image = imagecreatefromstring($imageData); | ||
$removeBackground = isset($settings['removeBackground']) && $settings['removeBackground'] === 'true'; | ||
if ($image !== false) { | ||
$tempFile = tempnam(sys_get_temp_dir(), 'logo'); | ||
imagepng($image, $tempFile); | ||
imagedestroy($image); | ||
|
||
$imagick = new Imagick($tempFile); | ||
if ($removeBackground) { | ||
$fuzz = Imagick::getQuantum() * 0.1; // 10% | ||
$imagick->transparentPaintImage("rgb(247, 247, 247)", 0, $fuzz, false); | ||
} | ||
$imagick->setImageFormat('png'); | ||
$imagick->writeImage($uploadFile); | ||
|
||
$imagick->clear(); | ||
$imagick->destroy(); | ||
unlink($tempFile); | ||
|
||
return true; | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
function resizeAndUploadLogo($uploadedFile, $uploadDir, $name) { $targetWidth = 70; | ||
$targetHeight = 48; | ||
|
||
$timestamp = time(); | ||
$originalFileName = $uploadedFile['name']; | ||
$fileExtension = pathinfo($originalFileName, PATHINFO_EXTENSION); | ||
$fileName = $timestamp . '-payments-' . sanitizeFilename($name) . '.' . $fileExtension; | ||
$uploadFile = $uploadDir . $fileName; | ||
|
||
if (move_uploaded_file($uploadedFile['tmp_name'], $uploadFile)) { | ||
$fileInfo = getimagesize($uploadFile); | ||
|
||
if ($fileInfo !== false) { | ||
$width = $fileInfo[0]; | ||
$height = $fileInfo[1]; | ||
|
||
// Load the image based on its format | ||
if ($fileExtension === 'png') { | ||
$image = imagecreatefrompng($uploadFile); | ||
} elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') { | ||
$image = imagecreatefromjpeg($uploadFile); | ||
} else { | ||
// Handle other image formats as needed | ||
return ""; | ||
} | ||
|
||
// Enable alpha channel (transparency) for PNG images | ||
if ($fileExtension === 'png') { | ||
imagesavealpha($image, true); | ||
} | ||
|
||
$newWidth = $width; | ||
$newHeight = $height; | ||
|
||
if ($width > $targetWidth) { | ||
$newWidth = $targetWidth; | ||
$newHeight = ($targetWidth / $width) * $height; | ||
} | ||
|
||
if ($newHeight > $targetHeight) { | ||
$newWidth = ($targetHeight / $newHeight) * $newWidth; | ||
$newHeight = $targetHeight; | ||
} | ||
|
||
$resizedImage = imagecreatetruecolor($newWidth, $newHeight); | ||
imagesavealpha($resizedImage, true); | ||
$transparency = imagecolorallocatealpha($resizedImage, 0, 0, 0, 127); | ||
imagefill($resizedImage, 0, 0, $transparency); | ||
imagecopyresampled($resizedImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height); | ||
|
||
if ($fileExtension === 'png') { | ||
imagepng($resizedImage, $uploadFile); | ||
} elseif ($fileExtension === 'jpg' || $fileExtension === 'jpeg') { | ||
imagejpeg($resizedImage, $uploadFile); | ||
} else { | ||
return ""; | ||
} | ||
|
||
imagedestroy($image); | ||
imagedestroy($resizedImage); | ||
return $fileName; | ||
} | ||
} | ||
|
||
return ""; | ||
} | ||
|
||
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { | ||
if ($_SERVER["REQUEST_METHOD"] === "POST") { | ||
$enabled = 1; | ||
$name = validate($_POST["paymentname"]); | ||
$iconUrl = validate($_POST['icon-url']); | ||
|
||
if ($name === "" || ($iconUrl === "" && empty($_FILES['paymenticon']['name']))) { | ||
$response = [ | ||
"success" => false, | ||
"errorMessage" => translate('fill_all_fields', $i18n) | ||
]; | ||
echo json_encode($response); | ||
exit(); | ||
} | ||
|
||
|
||
$icon = ""; | ||
|
||
if($iconUrl !== "") { | ||
$icon = getLogoFromUrl($iconUrl, '../../images/uploads/logos/', $name); | ||
} else { | ||
if (!empty($_FILES['paymenticon']['name'])) { | ||
$icon = resizeAndUploadLogo($_FILES['paymenticon'], '../../images/uploads/logos/', $name); | ||
} | ||
} | ||
|
||
$sql = "INSERT INTO payment_methods (name, icon, enabled) VALUES (:name, :icon, :enabled)"; | ||
|
||
$stmt = $db->prepare($sql); | ||
|
||
$stmt->bindParam(':name', $name, SQLITE3_TEXT); | ||
$stmt->bindParam(':icon', $icon, SQLITE3_TEXT); | ||
$stmt->bindParam(':enabled', $enabled, SQLITE3_INTEGER); | ||
|
||
if ($stmt->execute()) { | ||
$success['success'] = true; | ||
$success['message'] = translate('payment_method_added_successfuly', $i18n); | ||
$json = json_encode($success); | ||
header('Content-Type: application/json'); | ||
echo $json; | ||
exit(); | ||
} else { | ||
echo translate('error', $i18n) . ": " . $db->lastErrorMsg(); | ||
} | ||
} | ||
} | ||
$db->close(); | ||
|
||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
|
||
require_once '../../includes/connect_endpoint.php'; | ||
session_start(); | ||
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { | ||
if ($_SERVER["REQUEST_METHOD"] === "DELETE") { | ||
$paymentMethodId = $_GET["id"]; | ||
$deleteQuery = "DELETE FROM payment_methods WHERE id = :paymentMethodId"; | ||
$deleteStmt = $db->prepare($deleteQuery); | ||
$deleteStmt->bindParam(':paymentMethodId', $paymentMethodId, SQLITE3_INTEGER); | ||
|
||
if ($deleteStmt->execute()) { | ||
$success['success'] = true; | ||
$success['message'] = translate('payment_method_added_successfuly', $i18n); | ||
$json = json_encode($success); | ||
header('Content-Type: application/json'); | ||
echo $json; | ||
} else { | ||
http_response_code(500); | ||
echo json_encode(array("message" => translate('error', $i18n))); | ||
} | ||
} else { | ||
http_response_code(405); | ||
echo json_encode(array("message" => translate('invalid_request_method', $i18n))); | ||
} | ||
} | ||
$db->close(); | ||
|
||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<?php | ||
|
||
require_once '../../includes/connect_endpoint.php'; | ||
session_start(); | ||
|
||
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { | ||
$paymentsInUseQuery = $db->query('SELECT id FROM payment_methods WHERE id IN (SELECT DISTINCT payment_method_id FROM subscriptions)'); | ||
$paymentsInUse = []; | ||
while ($row = $paymentsInUseQuery->fetchArray(SQLITE3_ASSOC)) { | ||
$paymentsInUse[] = $row['id']; | ||
} | ||
|
||
$sql = "SELECT * FROM payment_methods"; | ||
|
||
$result = $db->query($sql); | ||
if ($result) { | ||
$payments = array(); | ||
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { | ||
$payments[] = $row; | ||
} | ||
} else { | ||
http_response_code(500); | ||
echo json_encode(array("message" => translate('error', $i18n))); | ||
exit(); | ||
} | ||
|
||
foreach ($payments as $payment) { | ||
$paymentIconFolder = $payment['id'] <= 31 ? 'images/uploads/icons/' : 'images/uploads/logos/'; | ||
$inUse = in_array($payment['id'], $paymentsInUse); | ||
?> | ||
<div class="payments-payment" | ||
data-enabled="<?= $payment['enabled']; ?>" | ||
data-in-use="<?= $inUse ? 'yes' : 'no' ?>" | ||
data-paymentid="<?= $payment['id'] ?>" | ||
title="<?= $inUse ? translate('cant_delete_payment_method_in_use', $i18n) : ($payment['enabled'] ? translate('disable', $i18n) : translate('enable', $i18n)) ?>" | ||
onClick="togglePayment(<?= $payment['id'] ?>)"> | ||
<img src="<?= $paymentIconFolder.$payment['icon'] ?>" alt="Logo" /> | ||
<span class="payment-name"> | ||
<?= $payment['name'] ?> | ||
</span> | ||
<?php | ||
if ($payment['id'] > 31 && !$inUse) { | ||
?> | ||
<div class="delete-payment-method" title="<?= translate('delete', $i18n) ?>" data-paymentid="<?= $payment['id'] ?>" onclick="deletePaymentMethod(<?= $payment['id'] ?>)"> | ||
x | ||
</div> | ||
<?php | ||
} | ||
?> | ||
</div> | ||
<?php | ||
} | ||
} else { | ||
http_response_code(401); | ||
echo json_encode(array("message" => translate('error', $i18n))); | ||
exit(); | ||
} | ||
|
||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
<?php | ||
if (isset($_GET['search'])) { | ||
$searchTerm = urlencode($_GET['search'] . " logo"); | ||
|
||
$url = "https://www.google.com/search?q={$searchTerm}&tbm=isch"; | ||
$backupUrl = "https://search.brave.com/search?q={$searchTerm}"; | ||
|
||
$ch = curl_init(); | ||
curl_setopt($ch, CURLOPT_URL, $url); | ||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
|
||
// Convert all environment variable keys to lowercase | ||
$envVars = array_change_key_case($_SERVER, CASE_LOWER); | ||
|
||
// Check for http_proxy or https_proxy environment variables | ||
$httpProxy = isset($envVars['http_proxy']) ? $envVars['http_proxy'] : null; | ||
$httpsProxy = isset($envVars['https_proxy']) ? $envVars['https_proxy'] : null; | ||
|
||
if (!empty($httpProxy)) { | ||
curl_setopt($ch, CURLOPT_PROXY, $httpProxy); | ||
} elseif (!empty($httpsProxy)) { | ||
curl_setopt($ch, CURLOPT_PROXY, $httpsProxy); | ||
} | ||
|
||
$response = curl_exec($ch); | ||
|
||
if ($response === false) { | ||
// If cURL fails to access google images, use brave image search as a backup | ||
$ch = curl_init(); | ||
curl_setopt($ch, CURLOPT_URL, $backupUrl); | ||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
$envVars = array_change_key_case($_SERVER, CASE_LOWER); | ||
$httpProxy = isset($envVars['http_proxy']) ? $envVars['http_proxy'] : null; | ||
$httpsProxy = isset($envVars['https_proxy']) ? $envVars['https_proxy'] : null; | ||
if (!empty($httpProxy)) { | ||
curl_setopt($ch, CURLOPT_PROXY, $httpProxy); | ||
} elseif (!empty($httpsProxy)) { | ||
curl_setopt($ch, CURLOPT_PROXY, $httpsProxy); | ||
} | ||
$response = curl_exec($ch); | ||
if ($response === false) { | ||
echo json_encode(['error' => 'Failed to fetch data from Google.']); | ||
} else { | ||
$imageUrls = extractImageUrlsFromPage($response); | ||
header('Content-Type: application/json'); | ||
echo json_encode(['imageUrls' => $imageUrls]); | ||
} | ||
} else { | ||
// Parse the HTML response to extract image URLs | ||
$imageUrls = extractImageUrlsFromPage($response); | ||
|
||
// Pass the image URLs to the client | ||
header('Content-Type: application/json'); | ||
echo json_encode(['imageUrls' => $imageUrls]); | ||
} | ||
|
||
curl_close($ch); | ||
} else { | ||
echo json_encode(['error' => 'Invalid request.']); | ||
} | ||
|
||
function extractImageUrlsFromPage($html) { | ||
$imageUrls = []; | ||
|
||
$doc = new DOMDocument(); | ||
@$doc->loadHTML($html); | ||
|
||
$imgTags = $doc->getElementsByTagName('img'); | ||
foreach ($imgTags as $imgTag) { | ||
$src = $imgTag->getAttribute('src'); | ||
if (!strstr($imgTag->getAttribute('class'), "favicon") && !strstr($imgTag->getAttribute('class'), "logo")) { | ||
if (filter_var($src, FILTER_VALIDATE_URL)) { | ||
$imageUrls[] = $src; | ||
} | ||
} | ||
} | ||
|
||
return $imageUrls; | ||
} | ||
|
||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.