Revert "Merge branch 'development' into main"
This reverts commit3810b487cd
, reversing changes made tod9a41840ce
.
This commit is contained in:
parent
3810b487cd
commit
0c067e26c8
171 changed files with 5028 additions and 7477 deletions
|
@ -62,6 +62,3 @@ PUSHER_APP_CLUSTER=mt1
|
|||
|
||||
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
|
||||
# Settings Cache
|
||||
SETTINGS_CACHE_ENABLED=true
|
|
@ -2,68 +2,46 @@
|
|||
|
||||
namespace App\Classes;
|
||||
|
||||
use App\Models\Pterodactyl\Egg;
|
||||
use App\Models\Pterodactyl\Nest;
|
||||
use App\Models\Pterodactyl\Node;
|
||||
use App\Models\Egg;
|
||||
use App\Models\Nest;
|
||||
use App\Models\Node;
|
||||
use App\Models\Product;
|
||||
use App\Models\Server;
|
||||
use App\Models\User;
|
||||
use Exception;
|
||||
use Illuminate\Http\Client\PendingRequest;
|
||||
use Illuminate\Http\Client\Response;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use App\Settings\PterodactylSettings;
|
||||
use App\Settings\ServerSettings;
|
||||
|
||||
class PterodactylClient
|
||||
class Pterodactyl
|
||||
{
|
||||
//TODO: Extend error handling (maybe logger for more errors when debugging)
|
||||
|
||||
private int $per_page_limit = 200;
|
||||
|
||||
private int $allocation_limit = 200;
|
||||
|
||||
public PendingRequest $client;
|
||||
|
||||
public PendingRequest $application;
|
||||
|
||||
public function __construct(PterodactylSettings $ptero_settings)
|
||||
{
|
||||
$server_settings = new ServerSettings();
|
||||
|
||||
try {
|
||||
$this->client = $this->client($ptero_settings);
|
||||
$this->application = $this->clientAdmin($ptero_settings);
|
||||
$this->per_page_limit = $ptero_settings->per_page_limit;
|
||||
$this->allocation_limit = $server_settings->allocation_limit;
|
||||
} catch (Exception $exception) {
|
||||
logger('Failed to construct Pterodactyl client, Settings table not available?', ['exception' => $exception]);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @return PendingRequest
|
||||
*/
|
||||
public function client(PterodactylSettings $ptero_settings)
|
||||
public static function client()
|
||||
{
|
||||
return Http::withHeaders([
|
||||
'Authorization' => 'Bearer ' . $ptero_settings->user_token,
|
||||
'Authorization' => 'Bearer ' . config('SETTINGS::SYSTEM:PTERODACTYL:TOKEN'),
|
||||
'Content-type' => 'application/json',
|
||||
'Accept' => 'Application/vnd.pterodactyl.v1+json',
|
||||
])->baseUrl($ptero_settings->getUrl() . 'api' . '/');
|
||||
])->baseUrl(config('SETTINGS::SYSTEM:PTERODACTYL:URL') . '/api');
|
||||
}
|
||||
|
||||
public function clientAdmin(PterodactylSettings $ptero_settings)
|
||||
public static function clientAdmin()
|
||||
{
|
||||
return Http::withHeaders([
|
||||
'Authorization' => 'Bearer ' . $ptero_settings->admin_token,
|
||||
'Authorization' => 'Bearer ' . config('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN'),
|
||||
'Content-type' => 'application/json',
|
||||
'Accept' => 'Application/vnd.pterodactyl.v1+json',
|
||||
])->baseUrl($ptero_settings->getUrl() . 'api' . '/');
|
||||
])->baseUrl(config('SETTINGS::SYSTEM:PTERODACTYL:URL') . '/api');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Exception
|
||||
*/
|
||||
private function getException(string $message = '', int $status = 0): Exception
|
||||
private static function getException(string $message = '', int $status = 0): Exception
|
||||
{
|
||||
if ($status == 404) {
|
||||
return new Exception('Ressource does not exist on pterodactyl - ' . $message, 404);
|
||||
|
@ -90,10 +68,10 @@ class PterodactylClient
|
|||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getEggs(Nest $nest)
|
||||
public static function getEggs(Nest $nest)
|
||||
{
|
||||
try {
|
||||
$response = $this->application->get("application/nests/{$nest->id}/eggs?include=nest,variables&per_page=" . $this->per_page_limit);
|
||||
$response = self::client()->get("/application/nests/{$nest->id}/eggs?include=nest,variables&per_page=" . config('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT'));
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -109,10 +87,10 @@ class PterodactylClient
|
|||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getNodes()
|
||||
public static function getNodes()
|
||||
{
|
||||
try {
|
||||
$response = $this->application->get('application/nodes?per_page=' . $this->per_page_limit);
|
||||
$response = self::client()->get('/application/nodes?per_page=' . config('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT'));
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -129,10 +107,10 @@ class PterodactylClient
|
|||
* @throws Exception
|
||||
* @description Returns the infos of a single node
|
||||
*/
|
||||
public function getNode($id)
|
||||
public static function getNode($id)
|
||||
{
|
||||
try {
|
||||
$response = $this->application->get('application/nodes/' . $id);
|
||||
$response = self::client()->get('/application/nodes/' . $id);
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -143,10 +121,10 @@ class PterodactylClient
|
|||
return $response->json()['attributes'];
|
||||
}
|
||||
|
||||
public function getServers()
|
||||
public static function getServers()
|
||||
{
|
||||
try {
|
||||
$response = $this->application->get('application/servers?per_page=' . $this->per_page_limit);
|
||||
$response = self::client()->get('/application/servers?per_page=' . config('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT'));
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -162,10 +140,10 @@ class PterodactylClient
|
|||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getNests()
|
||||
public static function getNests()
|
||||
{
|
||||
try {
|
||||
$response = $this->application->get('application/nests?per_page=' . $this->per_page_limit);
|
||||
$response = self::client()->get('/application/nests?per_page=' . config('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT'));
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -181,10 +159,10 @@ class PterodactylClient
|
|||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getLocations()
|
||||
public static function getLocations()
|
||||
{
|
||||
try {
|
||||
$response = $this->application->get('application/locations?per_page=' . $this->per_page_limit);
|
||||
$response = self::client()->get('/application/locations?per_page=' . config('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT'));
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -201,7 +179,7 @@ class PterodactylClient
|
|||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getFreeAllocationId(Node $node)
|
||||
public static function getFreeAllocationId(Node $node)
|
||||
{
|
||||
return self::getFreeAllocations($node)[0]['attributes']['id'] ?? null;
|
||||
}
|
||||
|
@ -212,7 +190,7 @@ class PterodactylClient
|
|||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getFreeAllocations(Node $node)
|
||||
public static function getFreeAllocations(Node $node)
|
||||
{
|
||||
$response = self::getAllocations($node);
|
||||
$freeAllocations = [];
|
||||
|
@ -236,10 +214,11 @@ class PterodactylClient
|
|||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getAllocations(Node $node)
|
||||
public static function getAllocations(Node $node)
|
||||
{
|
||||
$per_page = config('SETTINGS::SERVER:ALLOCATION_LIMIT', 200);
|
||||
try {
|
||||
$response = $this->application->get("application/nodes/{$node->id}/allocations?per_page={$this->allocation_limit}");
|
||||
$response = self::client()->get("/application/nodes/{$node->id}/allocations?per_page={$per_page}");
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -250,15 +229,24 @@ class PterodactylClient
|
|||
return $response->json();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $route
|
||||
* @return string
|
||||
*/
|
||||
public static function url(string $route): string
|
||||
{
|
||||
return config('SETTINGS::SYSTEM:PTERODACTYL:URL') . $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param Egg $egg
|
||||
* @param int $allocationId
|
||||
* @return Response
|
||||
*/
|
||||
public function createServer(Server $server, Egg $egg, int $allocationId)
|
||||
public static function createServer(Server $server, Egg $egg, int $allocationId)
|
||||
{
|
||||
return $this->application->post('application/servers', [
|
||||
return self::client()->post('/application/servers', [
|
||||
'name' => $server->name,
|
||||
'external_id' => $server->id,
|
||||
'user' => $server->user->pterodactyl_id,
|
||||
|
@ -284,10 +272,10 @@ class PterodactylClient
|
|||
]);
|
||||
}
|
||||
|
||||
public function suspendServer(Server $server)
|
||||
public static function suspendServer(Server $server)
|
||||
{
|
||||
try {
|
||||
$response = $this->application->post("application/servers/$server->pterodactyl_id/suspend");
|
||||
$response = self::client()->post("/application/servers/$server->pterodactyl_id/suspend");
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -298,10 +286,10 @@ class PterodactylClient
|
|||
return $response;
|
||||
}
|
||||
|
||||
public function unSuspendServer(Server $server)
|
||||
public static function unSuspendServer(Server $server)
|
||||
{
|
||||
try {
|
||||
$response = $this->application->post("application/servers/$server->pterodactyl_id/unsuspend");
|
||||
$response = self::client()->post("/application/servers/$server->pterodactyl_id/unsuspend");
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -321,7 +309,7 @@ class PterodactylClient
|
|||
public function getUser(int $pterodactylId)
|
||||
{
|
||||
try {
|
||||
$response = $this->application->get("application/users/{$pterodactylId}");
|
||||
$response = self::client()->get("/application/users/{$pterodactylId}");
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -338,10 +326,10 @@ class PterodactylClient
|
|||
* @param int $pterodactylId
|
||||
* @return mixed
|
||||
*/
|
||||
public function getServerAttributes(int $pterodactylId, bool $deleteOn404 = false)
|
||||
public static function getServerAttributes(int $pterodactylId, bool $deleteOn404 = false)
|
||||
{
|
||||
try {
|
||||
$response = $this->application->get("application/servers/{$pterodactylId}?include=egg,node,nest,location");
|
||||
$response = self::client()->get("/application/servers/{$pterodactylId}?include=egg,node,nest,location");
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -368,9 +356,9 @@ class PterodactylClient
|
|||
* @param Product $product
|
||||
* @return Response
|
||||
*/
|
||||
public function updateServer(Server $server, Product $product)
|
||||
public static function updateServer(Server $server, Product $product)
|
||||
{
|
||||
return $this->application->patch("application/servers/{$server->pterodactyl_id}/build", [
|
||||
return self::client()->patch("/application/servers/{$server->pterodactyl_id}/build", [
|
||||
'allocation' => $server->allocation,
|
||||
'memory' => $product->memory,
|
||||
'swap' => $product->swap,
|
||||
|
@ -393,9 +381,9 @@ class PterodactylClient
|
|||
* @param Server $server
|
||||
* @return mixed
|
||||
*/
|
||||
public function updateServerOwner(Server $server, int $userId)
|
||||
public static function updateServerOwner(Server $server, int $userId)
|
||||
{
|
||||
return $this->application->patch("application/servers/{$server->pterodactyl_id}/details", [
|
||||
return self::client()->patch("/application/servers/{$server->pterodactyl_id}/details", [
|
||||
'name' => $server->name,
|
||||
'user' => $userId,
|
||||
]);
|
||||
|
@ -408,9 +396,9 @@ class PterodactylClient
|
|||
* @param string $action
|
||||
* @return Response
|
||||
*/
|
||||
public function powerAction(Server $server, $action)
|
||||
public static function powerAction(Server $server, $action)
|
||||
{
|
||||
return $this->client->post("client/servers/{$server->identifier}/power", [
|
||||
return self::clientAdmin()->post("/client/servers/{$server->identifier}/power", [
|
||||
'signal' => $action,
|
||||
]);
|
||||
}
|
||||
|
@ -418,9 +406,9 @@ class PterodactylClient
|
|||
/**
|
||||
* Get info about user
|
||||
*/
|
||||
public function getClientUser()
|
||||
public static function getClientUser()
|
||||
{
|
||||
return $this->client->get('client/account');
|
||||
return self::clientAdmin()->get('/client/account');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -431,10 +419,10 @@ class PterodactylClient
|
|||
* @param int $requireDisk
|
||||
* @return bool
|
||||
*/
|
||||
public function checkNodeResources(Node $node, int $requireMemory, int $requireDisk)
|
||||
public static function checkNodeResources(Node $node, int $requireMemory, int $requireDisk)
|
||||
{
|
||||
try {
|
||||
$response = $this->application->get("application/nodes/{$node->id}");
|
||||
$response = self::client()->get("/application/nodes/{$node->id}");
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
47
app/Classes/Settings/Invoices.php
Normal file
47
app/Classes/Settings/Invoices.php
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Classes\Settings;
|
||||
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class Invoices
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function updateSettings(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'logo' => 'nullable|max:10000|mimes:jpg,png,jpeg',
|
||||
]);
|
||||
|
||||
$values = [
|
||||
//SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
|
||||
'SETTINGS::INVOICE:COMPANY_NAME' => 'company-name',
|
||||
'SETTINGS::INVOICE:COMPANY_ADDRESS' => 'company-address',
|
||||
'SETTINGS::INVOICE:COMPANY_PHONE' => 'company-phone',
|
||||
'SETTINGS::INVOICE:COMPANY_MAIL' => 'company-mail',
|
||||
'SETTINGS::INVOICE:COMPANY_VAT' => 'company-vat',
|
||||
'SETTINGS::INVOICE:COMPANY_WEBSITE' => 'company-web',
|
||||
'SETTINGS::INVOICE:PREFIX' => 'invoice-prefix',
|
||||
'SETTINGS::INVOICE:ENABLED' => 'enable-invoices',
|
||||
];
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
$param = $request->get($value);
|
||||
|
||||
Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
|
||||
Cache::forget('setting'.':'.$key);
|
||||
}
|
||||
|
||||
if ($request->hasFile('logo')) {
|
||||
$request->file('logo')->storeAs('public', 'logo.png');
|
||||
}
|
||||
|
||||
return redirect(route('admin.settings.index').'#invoices')->with('success', __('Invoice settings updated!'));
|
||||
}
|
||||
}
|
56
app/Classes/Settings/Language.php
Normal file
56
app/Classes/Settings/Language.php
Normal file
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace App\Classes\Settings;
|
||||
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class Language
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function updateSettings(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'autotranslate' => 'string',
|
||||
'canClientChangeLanguage' => 'string',
|
||||
'defaultLanguage' => 'required|string',
|
||||
'languages' => 'required|array',
|
||||
'languages.*' => 'required|string',
|
||||
'datatable-language' => 'required|string',
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return redirect(route('admin.settings.index').'#language')->with('error', __('Language settings have not been updated!'))->withErrors($validator);
|
||||
}
|
||||
|
||||
$values = [
|
||||
//SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
|
||||
'SETTINGS::LOCALE:DEFAULT' => 'defaultLanguage',
|
||||
'SETTINGS::LOCALE:DYNAMIC' => 'autotranslate',
|
||||
'SETTINGS::LOCALE:CLIENTS_CAN_CHANGE' => 'canClientChangeLanguage',
|
||||
'SETTINGS::LOCALE:AVAILABLE' => 'languages',
|
||||
'SETTINGS::LOCALE:DATATABLES' => 'datatable-language',
|
||||
];
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
$param = $request->get($value);
|
||||
|
||||
if (is_array($param)) {
|
||||
$param = implode(',', $param);
|
||||
}
|
||||
|
||||
Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
|
||||
Cache::forget('setting'.':'.$key);
|
||||
Session::remove('locale');
|
||||
}
|
||||
|
||||
return redirect(route('admin.settings.index').'#language')->with('success', __('Language settings updated!'));
|
||||
}
|
||||
}
|
107
app/Classes/Settings/Misc.php
Normal file
107
app/Classes/Settings/Misc.php
Normal file
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
namespace App\Classes\Settings;
|
||||
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class Misc
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function updateSettings(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'icon' => 'nullable|max:10000|mimes:jpg,png,jpeg',
|
||||
'favicon' => 'nullable|max:10000|mimes:ico',
|
||||
'discord-bot-token' => 'nullable|string',
|
||||
'discord-client-id' => 'nullable|string',
|
||||
'discord-client-secret' => 'nullable|string',
|
||||
'discord-guild-id' => 'nullable|string',
|
||||
'discord-invite-url' => 'nullable|string',
|
||||
'discord-role-id' => 'nullable|string',
|
||||
'recaptcha-site-key' => 'nullable|string',
|
||||
'recaptcha-secret-key' => 'nullable|string',
|
||||
'enable-recaptcha' => 'nullable|string',
|
||||
'mailservice' => 'nullable|string',
|
||||
'mailhost' => 'nullable|string',
|
||||
'mailport' => 'nullable|string',
|
||||
'mailusername' => 'nullable|string',
|
||||
'mailpassword' => 'nullable|string',
|
||||
'mailencryption' => 'nullable|string',
|
||||
'mailfromadress' => 'nullable|string',
|
||||
'mailfromname' => 'nullable|string',
|
||||
'enable_referral' => 'nullable|string',
|
||||
'referral_reward' => 'nullable|numeric',
|
||||
'referral_allowed' => 'nullable|string',
|
||||
'always_give_commission' => 'nullable|string',
|
||||
'referral_percentage' => 'nullable|numeric',
|
||||
'referral_mode' => 'nullable|string',
|
||||
'ticket_enabled' => 'nullable|string',
|
||||
'ticket_notify' => 'string',
|
||||
]);
|
||||
|
||||
$validator->after(function ($validator) use ($request) {
|
||||
// if enable-recaptcha is true then recaptcha-site-key and recaptcha-secret-key must be set
|
||||
if ($request->get('enable-recaptcha') == 'true' && (! $request->get('recaptcha-site-key') || ! $request->get('recaptcha-secret-key'))) {
|
||||
$validator->errors()->add('recaptcha-site-key', 'The site key is required if recaptcha is enabled.');
|
||||
$validator->errors()->add('recaptcha-secret-key', 'The secret key is required if recaptcha is enabled.');
|
||||
}
|
||||
});
|
||||
|
||||
if ($validator->fails()) {
|
||||
return redirect(route('admin.settings.index').'#misc')->with('error', __('Misc settings have not been updated!'))->withErrors($validator)
|
||||
->withInput();
|
||||
}
|
||||
|
||||
if ($request->hasFile('icon')) {
|
||||
$request->file('icon')->storeAs('public', 'icon.png');
|
||||
}
|
||||
if ($request->hasFile('favicon')) {
|
||||
$request->file('favicon')->storeAs('public', 'favicon.ico');
|
||||
}
|
||||
|
||||
$values = [
|
||||
'SETTINGS::DISCORD:BOT_TOKEN' => 'discord-bot-token',
|
||||
'SETTINGS::DISCORD:CLIENT_ID' => 'discord-client-id',
|
||||
'SETTINGS::DISCORD:CLIENT_SECRET' => 'discord-client-secret',
|
||||
'SETTINGS::DISCORD:GUILD_ID' => 'discord-guild-id',
|
||||
'SETTINGS::DISCORD:INVITE_URL' => 'discord-invite-url',
|
||||
'SETTINGS::DISCORD:ROLE_ID' => 'discord-role-id',
|
||||
'SETTINGS::RECAPTCHA:SITE_KEY' => 'recaptcha-site-key',
|
||||
'SETTINGS::RECAPTCHA:SECRET_KEY' => 'recaptcha-secret-key',
|
||||
'SETTINGS::RECAPTCHA:ENABLED' => 'enable-recaptcha',
|
||||
'SETTINGS::MAIL:MAILER' => 'mailservice',
|
||||
'SETTINGS::MAIL:HOST' => 'mailhost',
|
||||
'SETTINGS::MAIL:PORT' => 'mailport',
|
||||
'SETTINGS::MAIL:USERNAME' => 'mailusername',
|
||||
'SETTINGS::MAIL:PASSWORD' => 'mailpassword',
|
||||
'SETTINGS::MAIL:ENCRYPTION' => 'mailencryption',
|
||||
'SETTINGS::MAIL:FROM_ADDRESS' => 'mailfromadress',
|
||||
'SETTINGS::MAIL:FROM_NAME' => 'mailfromname',
|
||||
'SETTINGS::REFERRAL::ENABLED' => 'enable_referral',
|
||||
'SETTINGS::REFERRAL::REWARD' => 'referral_reward',
|
||||
'SETTINGS::REFERRAL::ALLOWED' => 'referral_allowed',
|
||||
'SETTINGS::REFERRAL:MODE' => 'referral_mode',
|
||||
'SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION' => 'always_give_commission',
|
||||
'SETTINGS::REFERRAL:PERCENTAGE' => 'referral_percentage',
|
||||
'SETTINGS::TICKET:ENABLED' => 'ticket_enabled',
|
||||
'SETTINGS::TICKET:NOTIFY' => 'ticket_notify',
|
||||
|
||||
];
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
$param = $request->get($value);
|
||||
|
||||
Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
|
||||
Cache::forget('setting'.':'.$key);
|
||||
}
|
||||
|
||||
return redirect(route('admin.settings.index').'#misc')->with('success', __('Misc settings updated!'));
|
||||
}
|
||||
}
|
58
app/Classes/Settings/Payments.php
Normal file
58
app/Classes/Settings/Payments.php
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace App\Classes\Settings;
|
||||
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class Payments
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function updateSettings(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'paypal-client_id' => 'nullable|string',
|
||||
'paypal-client-secret' => 'nullable|string',
|
||||
'paypal-sandbox-secret' => 'nullable|string',
|
||||
'stripe-secret-key' => 'nullable|string',
|
||||
'stripe-endpoint-secret' => 'nullable|string',
|
||||
'stripe-test-secret-key' => 'nullable|string',
|
||||
'stripe-test-endpoint-secret' => 'nullable|string',
|
||||
'stripe-methods' => 'nullable|string',
|
||||
'sales-tax' => 'nullable|numeric',
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
return redirect(route('admin.settings.index').'#payment')->with('error', __('Payment settings have not been updated!'))->withErrors($validator)
|
||||
->withInput();
|
||||
}
|
||||
|
||||
$values = [
|
||||
//SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
|
||||
'SETTINGS::PAYMENTS:PAYPAL:SECRET' => 'paypal-client-secret',
|
||||
'SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID' => 'paypal-client-id',
|
||||
'SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET' => 'paypal-sandbox-secret',
|
||||
'SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID' => 'paypal-sandbox-id',
|
||||
'SETTINGS::PAYMENTS:STRIPE:SECRET' => 'stripe-secret',
|
||||
'SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET' => 'stripe-endpoint-secret',
|
||||
'SETTINGS::PAYMENTS:STRIPE:TEST_SECRET' => 'stripe-test-secret',
|
||||
'SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET' => 'stripe-endpoint-test-secret',
|
||||
'SETTINGS::PAYMENTS:STRIPE:METHODS' => 'stripe-methods',
|
||||
'SETTINGS::PAYMENTS:SALES_TAX' => 'sales-tax',
|
||||
];
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
$param = $request->get($value);
|
||||
|
||||
Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
|
||||
Cache::forget('setting'.':'.$key);
|
||||
}
|
||||
|
||||
return redirect(route('admin.settings.index').'#payment')->with('success', __('Payment settings updated!'));
|
||||
}
|
||||
}
|
154
app/Classes/Settings/System.php
Normal file
154
app/Classes/Settings/System.php
Normal file
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
|
||||
namespace App\Classes\Settings;
|
||||
|
||||
use App\Classes\Pterodactyl;
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Qirolab\Theme\Theme;
|
||||
|
||||
|
||||
class System
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function checkPteroClientkey()
|
||||
{
|
||||
$response = Pterodactyl::getClientUser();
|
||||
|
||||
if ($response->failed()) {
|
||||
return redirect()->back()->with('error', __('Your Key or URL is not correct'));
|
||||
}
|
||||
|
||||
return redirect()->back()->with('success', __('Everything is good!'));
|
||||
}
|
||||
|
||||
public function updateSettings(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'register-ip-check' => 'string',
|
||||
'server-create-charge-first-hour' => 'string',
|
||||
'credits-display-name' => 'required|string',
|
||||
'allocation-limit' => 'required|min:0|integer',
|
||||
'force-email-verification' => 'string',
|
||||
'force-discord-verification' => 'string',
|
||||
'initial-credits' => 'required|min:0|integer',
|
||||
'initial-server-limit' => 'required|min:0|integer',
|
||||
'credits-reward-amount-discord' => 'required|min:0|integer',
|
||||
'credits-reward-amount-email' => 'required|min:0|integer',
|
||||
'server-limit-discord' => 'required|min:0|integer',
|
||||
'server-limit-email' => 'required|min:0|integer',
|
||||
'server-limit-purchase' => 'required|min:0|integer',
|
||||
'pterodactyl-api-key' => 'required|string',
|
||||
'pterodactyl-url' => 'required|string',
|
||||
'per-page-limit' => 'required|min:0|integer',
|
||||
'pterodactyl-admin-api-key' => 'required|string',
|
||||
'enable-upgrades' => 'string',
|
||||
'enable-disable-servers' => 'string',
|
||||
'enable-disable-new-users' => 'string',
|
||||
'show-imprint' => 'string',
|
||||
'show-privacy' => 'string',
|
||||
'show-tos' => 'string',
|
||||
'alert-enabled' => 'string',
|
||||
'alter-type' => 'string',
|
||||
'alert-message' => 'string|nullable',
|
||||
'motd-enabled' => 'string',
|
||||
'usefullinks-enabled' => 'string',
|
||||
'motd-message' => 'string|nullable',
|
||||
'seo-title' => 'string|nullable',
|
||||
'seo-description' => 'string|nullable',
|
||||
]);
|
||||
|
||||
$validator->after(function ($validator) use ($request) {
|
||||
// if enable-recaptcha is true then recaptcha-site-key and recaptcha-secret-key must be set
|
||||
if ($request->get('enable-upgrades') == 'true' && (! $request->get('pterodactyl-admin-api-key'))) {
|
||||
$validator->errors()->add('pterodactyl-admin-api-key', 'The admin api key is required when upgrades are enabled.');
|
||||
}
|
||||
});
|
||||
|
||||
if ($validator->fails()) {
|
||||
return redirect(route('admin.settings.index').'#system')->with('error', __('System settings have not been updated!'))->withErrors($validator)
|
||||
->withInput();
|
||||
}
|
||||
|
||||
// update Icons from request
|
||||
$this->updateIcons($request);
|
||||
|
||||
$values = [
|
||||
|
||||
"SETTINGS::SYSTEM:REGISTER_IP_CHECK" => "register-ip-check",
|
||||
"SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR" => "server-create-charge-first-hour",
|
||||
"SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME" => "credits-display-name",
|
||||
"SETTINGS::SERVER:ALLOCATION_LIMIT" => "allocation-limit",
|
||||
"SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER" => "minimum-credits",
|
||||
"SETTINGS::USER:FORCE_DISCORD_VERIFICATION" => "force-discord-verification",
|
||||
"SETTINGS::USER:FORCE_EMAIL_VERIFICATION" => "force-email-verification",
|
||||
"SETTINGS::USER:INITIAL_CREDITS" => "initial-credits",
|
||||
"SETTINGS::USER:INITIAL_SERVER_LIMIT" => "initial-server-limit",
|
||||
"SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD" => "credits-reward-amount-discord",
|
||||
"SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL" => "credits-reward-amount-email",
|
||||
"SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD" => "server-limit-discord",
|
||||
"SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL" => "server-limit-email",
|
||||
"SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE" => "server-limit-purchase",
|
||||
"SETTINGS::MISC:PHPMYADMIN:URL" => "phpmyadmin-url",
|
||||
"SETTINGS::SYSTEM:PTERODACTYL:URL" => "pterodactyl-url",
|
||||
'SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT' => "per-page-limit",
|
||||
"SETTINGS::SYSTEM:PTERODACTYL:TOKEN" => "pterodactyl-api-key",
|
||||
"SETTINGS::SYSTEM:ENABLE_LOGIN_LOGO" => "enable-login-logo",
|
||||
"SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN" => "pterodactyl-admin-api-key",
|
||||
"SETTINGS::SYSTEM:ENABLE_UPGRADE" => "enable-upgrade",
|
||||
"SETTINGS::SYSTEM:CREATION_OF_NEW_SERVERS" => "enable-disable-servers",
|
||||
"SETTINGS::SYSTEM:CREATION_OF_NEW_USERS" => "enable-disable-new-users",
|
||||
"SETTINGS::SYSTEM:SHOW_IMPRINT" => "show-imprint",
|
||||
"SETTINGS::SYSTEM:SHOW_PRIVACY" => "show-privacy",
|
||||
"SETTINGS::SYSTEM:SHOW_TOS" => "show-tos",
|
||||
"SETTINGS::SYSTEM:ALERT_ENABLED" => "alert-enabled",
|
||||
"SETTINGS::SYSTEM:ALERT_TYPE" => "alert-type",
|
||||
"SETTINGS::SYSTEM:ALERT_MESSAGE" => "alert-message",
|
||||
"SETTINGS::SYSTEM:THEME" => "theme",
|
||||
"SETTINGS::SYSTEM:MOTD_ENABLED" => "motd-enabled",
|
||||
"SETTINGS::SYSTEM:MOTD_MESSAGE" => "motd-message",
|
||||
"SETTINGS::SYSTEM:USEFULLINKS_ENABLED" => "usefullinks-enabled",
|
||||
"SETTINGS::SYSTEM:SEO_TITLE" => "seo-title",
|
||||
"SETTINGS::SYSTEM:SEO_DESCRIPTION" => "seo-description",
|
||||
];
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
$param = $request->get($value);
|
||||
|
||||
Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
|
||||
Cache::forget('setting'.':'.$key);
|
||||
}
|
||||
|
||||
//SET THEME
|
||||
$theme = $request->get('theme');
|
||||
Theme::set($theme);
|
||||
|
||||
|
||||
return redirect(route('admin.settings.index').'#system')->with('success', __('System settings updated!'));
|
||||
}
|
||||
|
||||
private function updateIcons(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'icon' => 'nullable|max:10000|mimes:jpg,png,jpeg',
|
||||
'logo' => 'nullable|max:10000|mimes:jpg,png,jpeg',
|
||||
'favicon' => 'nullable|max:10000|mimes:ico',
|
||||
]);
|
||||
|
||||
if ($request->hasFile('icon')) {
|
||||
$request->file('icon')->storeAs('public', 'icon.png');
|
||||
}
|
||||
if ($request->hasFile('logo')) {
|
||||
$request->file('logo')->storeAs('public', 'logo.png');
|
||||
}
|
||||
if ($request->hasFile('favicon')) {
|
||||
$request->file('favicon')->storeAs('public', 'favicon.ico');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,20 +2,18 @@
|
|||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Classes\PterodactylClient;
|
||||
use App\Classes\Pterodactyl;
|
||||
use App\Models\User;
|
||||
use App\Settings\PterodactylSettings;
|
||||
use App\Traits\Referral;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class MakeUserCommand extends Command
|
||||
{
|
||||
use Referral;
|
||||
|
||||
private $pterodactyl;
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
|
@ -30,14 +28,17 @@ class MakeUserCommand extends Command
|
|||
*/
|
||||
protected $description = 'Create an admin account with the Artisan Console';
|
||||
|
||||
private Pterodactyl $pterodactyl;
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
public function __construct(Pterodactyl $pterodactyl)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->pterodactyl = $pterodactyl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -46,9 +47,8 @@ class MakeUserCommand extends Command
|
|||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle(PterodactylSettings $ptero_settings)
|
||||
public function handle()
|
||||
{
|
||||
$this->pterodactyl = new PterodactylClient($ptero_settings);
|
||||
$ptero_id = $this->option('ptero_id') ?? $this->ask('Please specify your Pterodactyl ID.');
|
||||
$password = $this->secret('password') ?? $this->ask('Please specify your password.');
|
||||
|
||||
|
|
|
@ -1,146 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Extensions\PaymentGateways\Mollie;
|
||||
|
||||
use App\Helpers\AbstractExtension;
|
||||
use App\Events\PaymentEvent;
|
||||
use App\Events\UserUpdateCreditsEvent;
|
||||
use App\Models\PartnerDiscount;
|
||||
use App\Models\Payment;
|
||||
use App\Models\ShopProduct;
|
||||
use App\Models\User;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
/**
|
||||
* Summary of PayPalExtension
|
||||
*/
|
||||
class MollieExtension extends AbstractExtension
|
||||
{
|
||||
public static function getConfig(): array
|
||||
{
|
||||
return [
|
||||
"name" => "Mollie",
|
||||
"RoutesIgnoreCsrf" => [
|
||||
"payment/MollieWebhook"
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
static function pay(Request $request): void
|
||||
{
|
||||
$url = 'https://api.mollie.com/v2/payments';
|
||||
$settings = new MollieSettings();
|
||||
|
||||
$user = Auth::user();
|
||||
$shopProduct = ShopProduct::findOrFail($request->shopProduct);
|
||||
$discount = PartnerDiscount::getDiscount();
|
||||
|
||||
// create a new payment
|
||||
$payment = Payment::create([
|
||||
'user_id' => $user->id,
|
||||
'payment_id' => null,
|
||||
'payment_method' => 'mollie',
|
||||
'type' => $shopProduct->type,
|
||||
'status' => 'open',
|
||||
'amount' => $shopProduct->quantity,
|
||||
'price' => $shopProduct->price - ($shopProduct->price * $discount / 100),
|
||||
'tax_value' => $shopProduct->getTaxValue(),
|
||||
'tax_percent' => $shopProduct->getTaxPercent(),
|
||||
'total_price' => $shopProduct->getTotalPrice(),
|
||||
'currency_code' => $shopProduct->currency_code,
|
||||
'shop_item_product_id' => $shopProduct->id,
|
||||
]);
|
||||
|
||||
try {
|
||||
$response = Http::withHeaders([
|
||||
'Content-Type' => 'application/json',
|
||||
'Authorization' => 'Bearer ' . $settings->api_key,
|
||||
])->post($url, [
|
||||
'amount' => [
|
||||
'currency' => $shopProduct->currency_code,
|
||||
'value' => number_format($shopProduct->getTotalPrice(), 2, '.', ''),
|
||||
],
|
||||
'description' => "Order #{$payment->id} - " . $shopProduct->name,
|
||||
'redirectUrl' => route('payment.MollieSuccess'),
|
||||
'cancelUrl' => route('payment.Cancel'),
|
||||
'webhookUrl' => url('/extensions/payment/MollieWebhook'),
|
||||
'metadata' => [
|
||||
'payment_id' => $payment->id,
|
||||
],
|
||||
]);
|
||||
|
||||
if ($response->status() != 201) {
|
||||
Log::error('Mollie Payment: ' . $response->body());
|
||||
$payment->delete();
|
||||
|
||||
Redirect::route('store.index')->with('error', __('Payment failed'))->send();
|
||||
return;
|
||||
}
|
||||
|
||||
$payment->update([
|
||||
'payment_id' => $response->json()['id'],
|
||||
]);
|
||||
|
||||
Redirect::away($response->json()['_links']['checkout']['href'])->send();
|
||||
return;
|
||||
} catch (Exception $ex) {
|
||||
Log::error('Mollie Payment: ' . $ex->getMessage());
|
||||
$payment->delete();
|
||||
|
||||
Redirect::route('store.index')->with('error', __('Payment failed'))->send();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static function success(Request $request): void
|
||||
{
|
||||
$payment = Payment::findOrFail($request->input('payment'));
|
||||
$payment->status = 'pending';
|
||||
|
||||
Redirect::route('home')->with('success', 'Your payment is being processed')->send();
|
||||
return;
|
||||
}
|
||||
|
||||
static function webhook(Request $request): JsonResponse
|
||||
{
|
||||
$url = 'https://api.mollie.com/v2/payments/' . $request->id;
|
||||
$settings = new MollieSettings();
|
||||
|
||||
try {
|
||||
$response = Http::withHeaders([
|
||||
'Content-Type' => 'application/json',
|
||||
'Authorization' => 'Bearer ' . $settings->api_key,
|
||||
])->get($url);
|
||||
if ($response->status() != 200) {
|
||||
Log::error('Mollie Payment Webhook: ' . $response->json()['title']);
|
||||
return response()->json(['success' => false]);
|
||||
}
|
||||
|
||||
$payment = Payment::findOrFail($response->json()['metadata']['payment_id']);
|
||||
$payment->status->update([
|
||||
'status' => $response->json()['status'],
|
||||
]);
|
||||
|
||||
$shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
|
||||
event(new PaymentEvent($payment, $payment, $shopProduct));
|
||||
|
||||
if ($response->json()['status'] == 'paid') {
|
||||
$user = User::findOrFail($payment->user_id);
|
||||
event(new UserUpdateCreditsEvent($user));
|
||||
}
|
||||
} catch (Exception $ex) {
|
||||
Log::error('Mollie Payment Webhook: ' . $ex->getMessage());
|
||||
return response()->json(['success' => false]);
|
||||
}
|
||||
|
||||
// return a 200 status code
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Extensions\PaymentGateways\Mollie;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class MollieSettings extends Settings
|
||||
{
|
||||
|
||||
public bool $enabled = false;
|
||||
public ?string $api_key;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'mollie';
|
||||
}
|
||||
|
||||
public static function encrypted(): array
|
||||
{
|
||||
return [
|
||||
'api_key',
|
||||
];
|
||||
}
|
||||
|
||||
public static function getOptionInputData()
|
||||
{
|
||||
return [
|
||||
'category_icon' => 'fas fa-dollar-sign',
|
||||
'api_key' => [
|
||||
'type' => 'string',
|
||||
'label' => 'API Key',
|
||||
'description' => 'The API Key of your Mollie App',
|
||||
],
|
||||
'enabled' => [
|
||||
'type' => 'boolean',
|
||||
'label' => 'Enabled',
|
||||
'description' => 'Enable or disable this payment gateway',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||
|
||||
class CreateMollieSettings extends SettingsMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$this->migrator->addEncrypted('mollie.api_key', null);
|
||||
$this->migrator->add('mollie.enabled', false);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$this->migrator->delete('mollie.api_key');
|
||||
$this->migrator->delete('mollie.enabled');
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use App\Extensions\PaymentGateways\Mollie\MollieExtension;
|
||||
|
||||
Route::middleware(['web', 'auth'])->group(function () {
|
||||
Route::get('payment/MolliePay/{shopProduct}', function () {
|
||||
MollieExtension::pay(request());
|
||||
})->name('payment.MolliePay');
|
||||
|
||||
Route::get(
|
||||
'payment/MollieSuccess',
|
||||
function () {
|
||||
MollieExtension::success(request());
|
||||
}
|
||||
)->name('payment.MollieSuccess');
|
||||
});
|
||||
|
||||
|
||||
Route::post('payment/MollieWebhook', function () {
|
||||
MollieExtension::webhook(request());
|
||||
})->name('payment.MollieWebhook');
|
|
@ -1,197 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Extensions\PaymentGateways\PayPal;
|
||||
|
||||
use App\Helpers\AbstractExtension;
|
||||
use App\Events\PaymentEvent;
|
||||
use App\Events\UserUpdateCreditsEvent;
|
||||
use App\Extensions\PaymentGateways\PayPal\PayPalSettings;
|
||||
use App\Models\PartnerDiscount;
|
||||
use App\Models\Payment;
|
||||
use App\Models\ShopProduct;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use PayPalCheckoutSdk\Core\PayPalHttpClient;
|
||||
use PayPalCheckoutSdk\Core\ProductionEnvironment;
|
||||
use PayPalCheckoutSdk\Core\SandboxEnvironment;
|
||||
use PayPalCheckoutSdk\Orders\OrdersCaptureRequest;
|
||||
use PayPalCheckoutSdk\Orders\OrdersCreateRequest;
|
||||
use PayPalHttp\HttpException;
|
||||
|
||||
|
||||
/**
|
||||
* Summary of PayPalExtension
|
||||
*/
|
||||
class PayPalExtension extends AbstractExtension
|
||||
{
|
||||
public static function getConfig(): array
|
||||
{
|
||||
return [
|
||||
"name" => "PayPal",
|
||||
"RoutesIgnoreCsrf" => [],
|
||||
];
|
||||
}
|
||||
|
||||
static function PaypalPay(Request $request): void
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = Auth::user();
|
||||
$shopProduct = ShopProduct::findOrFail($request->shopProduct);
|
||||
$discount = PartnerDiscount::getDiscount();
|
||||
|
||||
// create a new payment
|
||||
$payment = Payment::create([
|
||||
'user_id' => $user->id,
|
||||
'payment_id' => null,
|
||||
'payment_method' => 'paypal',
|
||||
'type' => $shopProduct->type,
|
||||
'status' => 'open',
|
||||
'amount' => $shopProduct->quantity,
|
||||
'price' => $shopProduct->price - ($shopProduct->price * $discount / 100),
|
||||
'tax_value' => $shopProduct->getTaxValue(),
|
||||
'tax_percent' => $shopProduct->getTaxPercent(),
|
||||
'total_price' => $shopProduct->getTotalPrice(),
|
||||
'currency_code' => $shopProduct->currency_code,
|
||||
'shop_item_product_id' => $shopProduct->id,
|
||||
]);
|
||||
|
||||
$request = new OrdersCreateRequest();
|
||||
$request->prefer('return=representation');
|
||||
$request->body = [
|
||||
"intent" => "CAPTURE",
|
||||
"purchase_units" => [
|
||||
[
|
||||
"reference_id" => uniqid(),
|
||||
"description" => $shopProduct->display . ($discount ? (" (" . __('Discount') . " " . $discount . '%)') : ""),
|
||||
"amount" => [
|
||||
"value" => $shopProduct->getTotalPrice(),
|
||||
'currency_code' => strtoupper($shopProduct->currency_code),
|
||||
'breakdown' => [
|
||||
'item_total' =>
|
||||
[
|
||||
'currency_code' => strtoupper($shopProduct->currency_code),
|
||||
'value' => $shopProduct->getPriceAfterDiscount(),
|
||||
],
|
||||
'tax_total' =>
|
||||
[
|
||||
'currency_code' => strtoupper($shopProduct->currency_code),
|
||||
'value' => $shopProduct->getTaxValue(),
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
"application_context" => [
|
||||
"cancel_url" => route('payment.Cancel'),
|
||||
"return_url" => route('payment.PayPalSuccess', ['payment' => $payment->id]),
|
||||
'brand_name' => config('app.name', 'Controlpanel.GG'),
|
||||
'shipping_preference' => 'NO_SHIPPING'
|
||||
]
|
||||
|
||||
|
||||
];
|
||||
|
||||
try {
|
||||
// Call API with your client and get a response for your call
|
||||
$response = self::getPayPalClient()->execute($request);
|
||||
|
||||
// check for any errors in the response
|
||||
if ($response->statusCode != 201) {
|
||||
throw new \Exception($response->statusCode);
|
||||
}
|
||||
|
||||
// make sure the link is not empty
|
||||
if (empty($response->result->links[1]->href)) {
|
||||
throw new \Exception('No redirect link found');
|
||||
}
|
||||
|
||||
Redirect::away($response->result->links[1]->href)->send();
|
||||
return;
|
||||
} catch (HttpException $ex) {
|
||||
Log::error('PayPal Payment: ' . $ex->getMessage());
|
||||
$payment->delete();
|
||||
|
||||
Redirect::route('store.index')->with('error', __('Payment failed'))->send();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static function PaypalSuccess(Request $laravelRequest): void
|
||||
{
|
||||
$user = Auth::user();
|
||||
$user = User::findOrFail($user->id);
|
||||
|
||||
$payment = Payment::findOrFail($laravelRequest->payment);
|
||||
$shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
|
||||
|
||||
$request = new OrdersCaptureRequest($laravelRequest->input('token'));
|
||||
$request->prefer('return=representation');
|
||||
|
||||
try {
|
||||
// Call API with your client and get a response for your call
|
||||
$response = self::getPayPalClient()->execute($request);
|
||||
if ($response->statusCode == 201 || $response->statusCode == 200) {
|
||||
//update payment
|
||||
$payment->update([
|
||||
'status' => 'paid',
|
||||
'payment_id' => $response->result->id,
|
||||
]);
|
||||
|
||||
event(new UserUpdateCreditsEvent($user));
|
||||
event(new PaymentEvent($user, $payment, $shopProduct));
|
||||
|
||||
// redirect to the payment success page with success message
|
||||
Redirect::route('home')->with('success', 'Payment successful')->send();
|
||||
} elseif (env('APP_ENV') == 'local') {
|
||||
// If call returns body in response, you can get the deserialized version from the result attribute of the response
|
||||
$payment->delete();
|
||||
dd($response);
|
||||
} else {
|
||||
$payment->update([
|
||||
'status' => 'cancelled',
|
||||
'payment_id' => $response->result->id,
|
||||
]);
|
||||
abort(500);
|
||||
}
|
||||
} catch (HttpException $ex) {
|
||||
if (env('APP_ENV') == 'local') {
|
||||
echo $ex->statusCode;
|
||||
$payment->delete();
|
||||
dd($ex->getMessage());
|
||||
} else {
|
||||
$payment->update([
|
||||
'status' => 'cancelled',
|
||||
'payment_id' => $response->result->id,
|
||||
]);
|
||||
abort(422);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function getPayPalClient(): PayPalHttpClient
|
||||
{
|
||||
$environment = env('APP_ENV') == 'local'
|
||||
? new SandboxEnvironment(self::getPaypalClientId(), self::getPaypalClientSecret())
|
||||
: new ProductionEnvironment(self::getPaypalClientId(), self::getPaypalClientSecret());
|
||||
return new PayPalHttpClient($environment);
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
static function getPaypalClientId(): string
|
||||
{
|
||||
$settings = new PayPalSettings();
|
||||
return env('APP_ENV') == 'local' ? $settings->sandbox_client_id : $settings->client_id;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
static function getPaypalClientSecret(): string
|
||||
{
|
||||
$settings = new PayPalSettings();
|
||||
return env('APP_ENV') == 'local' ? $settings->sandbox_client_secret : $settings->client_secret;
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Extensions\PaymentGateways\PayPal;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class PayPalSettings extends Settings
|
||||
{
|
||||
public bool $enabled = false;
|
||||
public ?string $client_id;
|
||||
public ?string $client_secret;
|
||||
public ?string $sandbox_client_id;
|
||||
public ?string $sandbox_client_secret;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'paypal';
|
||||
}
|
||||
|
||||
|
||||
public static function encrypted(): array
|
||||
{
|
||||
return [
|
||||
'client_id',
|
||||
'client_secret',
|
||||
'sandbox_client_id',
|
||||
'sandbox_client_secret'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of optionInputData array
|
||||
* Only used for the settings page
|
||||
* @return array<array<'type'|'label'|'description'|'options', string|bool|float|int|array<string, string>>>
|
||||
*/
|
||||
public static function getOptionInputData()
|
||||
{
|
||||
return [
|
||||
'category_icon' => 'fas fa-dollar-sign',
|
||||
'client_id' => [
|
||||
'type' => 'string',
|
||||
'label' => 'Client ID',
|
||||
'description' => 'The Client ID of your PayPal App',
|
||||
],
|
||||
'client_secret' => [
|
||||
'type' => 'string',
|
||||
'label' => 'Client Secret',
|
||||
'description' => 'The Client Secret of your PayPal App',
|
||||
],
|
||||
'enabled' => [
|
||||
'type' => 'boolean',
|
||||
'label' => 'Enabled',
|
||||
'description' => 'Enable this payment gateway',
|
||||
],
|
||||
'sandbox_client_id' => [
|
||||
'type' => 'string',
|
||||
'label' => 'Sandbox Client ID',
|
||||
'description' => 'The Sandbox Client ID used when app_env = local',
|
||||
],
|
||||
'sandbox_client_secret' => [
|
||||
'type' => 'string',
|
||||
'label' => 'Sandbox Client Secret',
|
||||
'description' => 'The Sandbox Client Secret used when app_env = local',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
13
app/Extensions/PaymentGateways/PayPal/config.php
Normal file
13
app/Extensions/PaymentGateways/PayPal/config.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace App\Extensions\PaymentGateways\PayPal;
|
||||
|
||||
function getConfig()
|
||||
{
|
||||
return [
|
||||
"name" => "PayPal",
|
||||
"description" => "PayPal payment gateway",
|
||||
"RoutesIgnoreCsrf" => [],
|
||||
"enabled" => (config('SETTINGS::PAYMENTS:PAYPAL:SECRET') && config('SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID')) || (config('SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET') && config('SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID') && env("APP_ENV") === "local"),
|
||||
];
|
||||
}
|
186
app/Extensions/PaymentGateways/PayPal/index.php
Normal file
186
app/Extensions/PaymentGateways/PayPal/index.php
Normal file
|
@ -0,0 +1,186 @@
|
|||
<?php
|
||||
|
||||
use App\Events\PaymentEvent;
|
||||
use App\Events\UserUpdateCreditsEvent;
|
||||
use App\Models\PartnerDiscount;
|
||||
use App\Models\Payment;
|
||||
use App\Models\ShopProduct;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use PayPalCheckoutSdk\Core\PayPalHttpClient;
|
||||
use PayPalCheckoutSdk\Core\ProductionEnvironment;
|
||||
use PayPalCheckoutSdk\Core\SandboxEnvironment;
|
||||
use PayPalCheckoutSdk\Orders\OrdersCaptureRequest;
|
||||
use PayPalCheckoutSdk\Orders\OrdersCreateRequest;
|
||||
use PayPalHttp\HttpException;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param ShopProduct $shopProduct
|
||||
*/
|
||||
function PaypalPay(Request $request)
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = Auth::user();
|
||||
$shopProduct = ShopProduct::findOrFail($request->shopProduct);
|
||||
$discount = PartnerDiscount::getDiscount();
|
||||
|
||||
// create a new payment
|
||||
$payment = Payment::create([
|
||||
'user_id' => $user->id,
|
||||
'payment_id' => null,
|
||||
'payment_method' => 'paypal',
|
||||
'type' => $shopProduct->type,
|
||||
'status' => 'open',
|
||||
'amount' => $shopProduct->quantity,
|
||||
'price' => $shopProduct->price - ($shopProduct->price * $discount / 100),
|
||||
'tax_value' => $shopProduct->getTaxValue(),
|
||||
'tax_percent' => $shopProduct->getTaxPercent(),
|
||||
'total_price' => $shopProduct->getTotalPrice(),
|
||||
'currency_code' => $shopProduct->currency_code,
|
||||
'shop_item_product_id' => $shopProduct->id,
|
||||
]);
|
||||
|
||||
$request = new OrdersCreateRequest();
|
||||
$request->prefer('return=representation');
|
||||
$request->body = [
|
||||
"intent" => "CAPTURE",
|
||||
"purchase_units" => [
|
||||
[
|
||||
"reference_id" => uniqid(),
|
||||
"description" => $shopProduct->display . ($discount ? (" (" . __('Discount') . " " . $discount . '%)') : ""),
|
||||
"amount" => [
|
||||
"value" => $shopProduct->getTotalPrice(),
|
||||
'currency_code' => strtoupper($shopProduct->currency_code),
|
||||
'breakdown' => [
|
||||
'item_total' =>
|
||||
[
|
||||
'currency_code' => strtoupper($shopProduct->currency_code),
|
||||
'value' => $shopProduct->getPriceAfterDiscount(),
|
||||
],
|
||||
'tax_total' =>
|
||||
[
|
||||
'currency_code' => strtoupper($shopProduct->currency_code),
|
||||
'value' => $shopProduct->getTaxValue(),
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
"application_context" => [
|
||||
"cancel_url" => route('payment.Cancel'),
|
||||
"return_url" => route('payment.PayPalSuccess', ['payment' => $payment->id]),
|
||||
'brand_name' => config('app.name', 'Controlpanel.GG'),
|
||||
'shipping_preference' => 'NO_SHIPPING'
|
||||
]
|
||||
|
||||
|
||||
];
|
||||
|
||||
try {
|
||||
// Call API with your client and get a response for your call
|
||||
$response = getPayPalClient()->execute($request);
|
||||
|
||||
// check for any errors in the response
|
||||
if ($response->statusCode != 201) {
|
||||
throw new \Exception($response->statusCode);
|
||||
}
|
||||
|
||||
// make sure the link is not empty
|
||||
if (empty($response->result->links[1]->href)) {
|
||||
throw new \Exception('No redirect link found');
|
||||
}
|
||||
|
||||
Redirect::away($response->result->links[1]->href)->send();
|
||||
return;
|
||||
} catch (HttpException $ex) {
|
||||
Log::error('PayPal Payment: ' . $ex->getMessage());
|
||||
$payment->delete();
|
||||
|
||||
Redirect::route('store.index')->with('error', __('Payment failed'))->send();
|
||||
return;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param Request $laravelRequest
|
||||
*/
|
||||
function PaypalSuccess(Request $laravelRequest)
|
||||
{
|
||||
$user = Auth::user();
|
||||
$user = User::findOrFail($user->id);
|
||||
|
||||
$payment = Payment::findOrFail($laravelRequest->payment);
|
||||
$shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
|
||||
|
||||
$request = new OrdersCaptureRequest($laravelRequest->input('token'));
|
||||
$request->prefer('return=representation');
|
||||
|
||||
try {
|
||||
// Call API with your client and get a response for your call
|
||||
$response = getPayPalClient()->execute($request);
|
||||
if ($response->statusCode == 201 || $response->statusCode == 200) {
|
||||
//update payment
|
||||
$payment->update([
|
||||
'status' => 'paid',
|
||||
'payment_id' => $response->result->id,
|
||||
]);
|
||||
|
||||
event(new UserUpdateCreditsEvent($user));
|
||||
event(new PaymentEvent($user, $payment, $shopProduct));
|
||||
|
||||
// redirect to the payment success page with success message
|
||||
Redirect::route('home')->with('success', 'Payment successful')->send();
|
||||
} elseif (env('APP_ENV') == 'local') {
|
||||
// If call returns body in response, you can get the deserialized version from the result attribute of the response
|
||||
$payment->delete();
|
||||
dd($response);
|
||||
} else {
|
||||
$payment->update([
|
||||
'status' => 'cancelled',
|
||||
'payment_id' => $response->result->id,
|
||||
]);
|
||||
abort(500);
|
||||
}
|
||||
} catch (HttpException $ex) {
|
||||
if (env('APP_ENV') == 'local') {
|
||||
echo $ex->statusCode;
|
||||
$payment->delete();
|
||||
dd($ex->getMessage());
|
||||
} else {
|
||||
$payment->update([
|
||||
'status' => 'cancelled',
|
||||
'payment_id' => $response->result->id,
|
||||
]);
|
||||
abort(422);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @return PayPalHttpClient
|
||||
*/
|
||||
function getPayPalClient()
|
||||
{
|
||||
$environment = env('APP_ENV') == 'local'
|
||||
? new SandboxEnvironment(getPaypalClientId(), getPaypalClientSecret())
|
||||
: new ProductionEnvironment(getPaypalClientId(), getPaypalClientSecret());
|
||||
return new PayPalHttpClient($environment);
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function getPaypalClientId()
|
||||
{
|
||||
return env('APP_ENV') == 'local' ? config("SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID") : config("SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID");
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function getPaypalClientSecret()
|
||||
{
|
||||
return env('APP_ENV') == 'local' ? config("SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET") : config("SETTINGS::PAYMENTS:PAYPAL:SECRET");
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
|
||||
class CreatePayPalSettings extends SettingsMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$table_exists = DB::table('settings_old')->exists();
|
||||
|
||||
|
||||
$this->migrator->addEncrypted('paypal.client_id', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID') : null);
|
||||
$this->migrator->addEncrypted('paypal.client_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:SECRET') : null);
|
||||
$this->migrator->addEncrypted('paypal.sandbox_client_id', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID') : null);
|
||||
$this->migrator->addEncrypted('paypal.sandbox_client_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET') : null);
|
||||
$this->migrator->add('paypal.enabled', false);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::table('settings_old')->insert([
|
||||
[
|
||||
'key' => 'SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID',
|
||||
'value' => $this->getNewValue('client_id'),
|
||||
'type' => 'string',
|
||||
'description' => 'The Client ID of your PayPal App'
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::PAYMENTS:PAYPAL:SECRET',
|
||||
'value' => $this->getNewValue('client_secret'),
|
||||
'type' => 'string',
|
||||
'description' => 'The Client Secret of your PayPal App'
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID',
|
||||
'value' => $this->getNewValue('sandbox_client_id'),
|
||||
'type' => 'string',
|
||||
'description' => 'The Sandbox Client ID of your PayPal App'
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET',
|
||||
'value' => $this->getNewValue('sandbox_client_secret'),
|
||||
'type' => 'string',
|
||||
'description' => 'The Sandbox Client Secret of your PayPal App'
|
||||
]
|
||||
]);
|
||||
|
||||
|
||||
$this->migrator->delete('paypal.client_id');
|
||||
$this->migrator->delete('paypal.client_secret');
|
||||
$this->migrator->delete('paypal.enabled');
|
||||
$this->migrator->delete('paypal.sandbox_client_id');
|
||||
$this->migrator->delete('paypal.sandbox_client_secret');
|
||||
}
|
||||
|
||||
public function getNewValue(string $name)
|
||||
{
|
||||
$new_value = DB::table('settings')->where([['group', '=', 'paypal'], ['name', '=', $name]])->get(['payload'])->first();
|
||||
|
||||
// Some keys returns '""' as a value.
|
||||
if ($new_value->payload === '""') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// remove the quotes from the string
|
||||
if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
|
||||
return substr($new_value->payload, 1, -1);
|
||||
}
|
||||
|
||||
return $new_value->payload;
|
||||
}
|
||||
|
||||
public function getOldValue(string $key)
|
||||
{
|
||||
// Always get the first value of the key.
|
||||
$old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
|
||||
|
||||
// Handle the old values to return without it being a string in all cases.
|
||||
if ($old_value->type === "string" || $old_value->type === "text") {
|
||||
if (is_null($old_value->value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Some values have the type string, but their values are boolean.
|
||||
if ($old_value->value === "false" || $old_value->value === "true") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return $old_value->value;
|
||||
}
|
||||
|
||||
if ($old_value->type === "boolean") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_INT);
|
||||
}
|
||||
}
|
|
@ -1,17 +1,18 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use App\Extensions\PaymentGateways\PayPal\PayPalExtension;
|
||||
|
||||
include_once(__DIR__ . '/index.php');
|
||||
|
||||
Route::middleware(['web', 'auth'])->group(function () {
|
||||
Route::get('payment/PayPalPay/{shopProduct}', function () {
|
||||
PayPalExtension::PaypalPay(request());
|
||||
PaypalPay(request());
|
||||
})->name('payment.PayPalPay');
|
||||
|
||||
Route::get(
|
||||
'payment/PayPalSuccess',
|
||||
function () {
|
||||
PayPalExtension::PaypalSuccess(request());
|
||||
PaypalSuccess(request());
|
||||
}
|
||||
)->name('payment.PayPalSuccess');
|
||||
});
|
||||
|
|
|
@ -1,390 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Extensions\PaymentGateways\Stripe;
|
||||
|
||||
use App\Helpers\AbstractExtension;
|
||||
use App\Events\PaymentEvent;
|
||||
use App\Events\UserUpdateCreditsEvent;
|
||||
use App\Extensions\PaymentGateways\Stripe\StripeSettings;
|
||||
use App\Models\PartnerDiscount;
|
||||
use App\Models\Payment;
|
||||
use App\Models\ShopProduct;
|
||||
use App\Models\User;
|
||||
use App\Notifications\ConfirmPaymentNotification;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Stripe\Exception\SignatureVerificationException;
|
||||
use Stripe\Stripe;
|
||||
use Stripe\StripeClient;
|
||||
|
||||
class StripeExtension extends AbstractExtension
|
||||
{
|
||||
public static function getConfig(): array
|
||||
{
|
||||
return [
|
||||
"name" => "Stripe",
|
||||
"RoutesIgnoreCsrf" => [
|
||||
"payment/StripeWebhooks",
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param ShopProduct $shopProduct
|
||||
*/
|
||||
public static function StripePay(Request $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
$shopProduct = ShopProduct::findOrFail($request->shopProduct);
|
||||
|
||||
// check if the price is valid for stripe
|
||||
if (!self::checkPriceAmount($shopProduct->getTotalPrice(), strtoupper($shopProduct->currency_code), 'stripe')) {
|
||||
Redirect::route('home')->with('error', __('The product you chose can\'t be purchased with this payment method. The total amount is too small. Please buy a bigger amount or try a different payment method.'))->send();
|
||||
return;
|
||||
}
|
||||
|
||||
$discount = PartnerDiscount::getDiscount();
|
||||
|
||||
|
||||
// create payment
|
||||
$payment = Payment::create([
|
||||
'user_id' => $user->id,
|
||||
'payment_id' => null,
|
||||
'payment_method' => 'stripe',
|
||||
'type' => $shopProduct->type,
|
||||
'status' => 'open',
|
||||
'amount' => $shopProduct->quantity,
|
||||
'price' => $shopProduct->price - ($shopProduct->price * $discount / 100),
|
||||
'tax_value' => $shopProduct->getTaxValue(),
|
||||
'total_price' => $shopProduct->getTotalPrice(),
|
||||
'tax_percent' => $shopProduct->getTaxPercent(),
|
||||
'currency_code' => $shopProduct->currency_code,
|
||||
'shop_item_product_id' => $shopProduct->id,
|
||||
]);
|
||||
|
||||
$stripeClient = self::getStripeClient();
|
||||
$request = $stripeClient->checkout->sessions->create([
|
||||
'line_items' => [
|
||||
[
|
||||
'price_data' => [
|
||||
'currency' => $shopProduct->currency_code,
|
||||
'product_data' => [
|
||||
'name' => $shopProduct->display . ($discount ? (' (' . __('Discount') . ' ' . $discount . '%)') : ''),
|
||||
'description' => $shopProduct->description,
|
||||
],
|
||||
'unit_amount_decimal' => round($shopProduct->getPriceAfterDiscount() * 100, 2),
|
||||
],
|
||||
'quantity' => 1,
|
||||
],
|
||||
[
|
||||
'price_data' => [
|
||||
'currency' => $shopProduct->currency_code,
|
||||
'product_data' => [
|
||||
'name' => __('Tax'),
|
||||
'description' => $shopProduct->getTaxPercent() . '%',
|
||||
],
|
||||
'unit_amount_decimal' => round($shopProduct->getTaxValue(), 2) * 100,
|
||||
],
|
||||
'quantity' => 1,
|
||||
],
|
||||
],
|
||||
|
||||
'mode' => 'payment',
|
||||
'success_url' => route('payment.StripeSuccess', ['payment' => $payment->id]) . '&session_id={CHECKOUT_SESSION_ID}',
|
||||
'cancel_url' => route('payment.Cancel'),
|
||||
'payment_intent_data' => [
|
||||
'metadata' => [
|
||||
'payment_id' => $payment->id,
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
Redirect::to($request->url)->send();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*/
|
||||
public static function StripeSuccess(Request $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
$user = User::findOrFail($user->id);
|
||||
$payment = Payment::findOrFail($request->input('payment'));
|
||||
$shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
|
||||
|
||||
|
||||
Redirect::route('home')->with('success', 'Please wait for success')->send();
|
||||
|
||||
$stripeClient = self::getStripeClient();
|
||||
try {
|
||||
//get stripe data
|
||||
$paymentSession = $stripeClient->checkout->sessions->retrieve($request->input('session_id'));
|
||||
$paymentIntent = $stripeClient->paymentIntents->retrieve($paymentSession->payment_intent);
|
||||
|
||||
//get DB entry of this payment ID if existing
|
||||
$paymentDbEntry = Payment::where('payment_id', $paymentSession->payment_intent)->count();
|
||||
|
||||
// check if payment is 100% completed and payment does not exist in db already
|
||||
if ($paymentSession->status == 'complete' && $paymentIntent->status == 'succeeded' && $paymentDbEntry == 0) {
|
||||
|
||||
//update payment
|
||||
$payment->update([
|
||||
'payment_id' => $paymentSession->payment_intent,
|
||||
'status' => 'paid',
|
||||
]);
|
||||
|
||||
//payment notification
|
||||
$user->notify(new ConfirmPaymentNotification($payment));
|
||||
|
||||
event(new UserUpdateCreditsEvent($user));
|
||||
event(new PaymentEvent($user, $payment, $shopProduct));
|
||||
|
||||
//redirect back to home
|
||||
Redirect::route('home')->with('success', 'Payment successful')->send();
|
||||
} else {
|
||||
if ($paymentIntent->status == 'processing') {
|
||||
|
||||
//update payment
|
||||
$payment->update([
|
||||
'payment_id' => $paymentSession->payment_intent,
|
||||
'status' => 'processing',
|
||||
]);
|
||||
|
||||
event(new PaymentEvent($user, $payment, $shopProduct));
|
||||
|
||||
Redirect::route('home')->with('success', 'Your payment is being processed')->send();
|
||||
}
|
||||
|
||||
if ($paymentDbEntry == 0 && $paymentIntent->status != 'processing') {
|
||||
$stripeClient->paymentIntents->cancel($paymentIntent->id);
|
||||
|
||||
//redirect back to home
|
||||
Redirect::route('home')->with('info', __('Your payment has been canceled!'))->send();
|
||||
} else {
|
||||
abort(402);
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
if (env('APP_ENV') == 'local') {
|
||||
dd($e->getMessage());
|
||||
} else {
|
||||
abort(422);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*/
|
||||
public static function handleStripePaymentSuccessHook($paymentIntent)
|
||||
{
|
||||
try {
|
||||
$payment = Payment::where('id', $paymentIntent->metadata->payment_id)->with('user')->first();
|
||||
$user = User::where('id', $payment->user_id)->first();
|
||||
$shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
|
||||
|
||||
if ($paymentIntent->status == 'succeeded' && $payment->status == 'processing') {
|
||||
|
||||
//update payment db entry status
|
||||
$payment->update([
|
||||
'payment_id' => $payment->payment_id ?? $paymentIntent->id,
|
||||
'status' => 'paid'
|
||||
]);
|
||||
|
||||
//payment notification
|
||||
$user->notify(new ConfirmPaymentNotification($payment));
|
||||
event(new UserUpdateCreditsEvent($user));
|
||||
event(new PaymentEvent($user, $payment, $shopProduct));
|
||||
}
|
||||
|
||||
// return 200
|
||||
return response()->json(['success' => true], 200);
|
||||
} catch (Exception $ex) {
|
||||
abort(422);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*/
|
||||
public static function StripeWebhooks(Request $request)
|
||||
{
|
||||
Stripe::setApiKey(self::getStripeSecret());
|
||||
|
||||
try {
|
||||
$payload = @file_get_contents('php://input');
|
||||
$sig_header = $request->header('Stripe-Signature');
|
||||
$event = null;
|
||||
$event = \Stripe\Webhook::constructEvent(
|
||||
$payload,
|
||||
$sig_header,
|
||||
self::getStripeEndpointSecret()
|
||||
);
|
||||
} catch (\UnexpectedValueException $e) {
|
||||
// Invalid payload
|
||||
|
||||
abort(400);
|
||||
} catch (SignatureVerificationException $e) {
|
||||
// Invalid signature
|
||||
|
||||
abort(400);
|
||||
}
|
||||
|
||||
// Handle the event
|
||||
switch ($event->type) {
|
||||
case 'payment_intent.succeeded':
|
||||
$paymentIntent = $event->data->object; // contains a \Stripe\PaymentIntent
|
||||
self::handleStripePaymentSuccessHook($paymentIntent);
|
||||
break;
|
||||
default:
|
||||
echo 'Received unknown event type ' . $event->type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Stripe\StripeClient
|
||||
*/
|
||||
public static function getStripeClient()
|
||||
{
|
||||
return new StripeClient(self::getStripeSecret());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getStripeSecret()
|
||||
{
|
||||
$settings = new StripeSettings();
|
||||
|
||||
return env('APP_ENV') == 'local'
|
||||
? $settings->test_secret_key
|
||||
: $settings->secret_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getStripeEndpointSecret()
|
||||
{
|
||||
$settings = new StripeSettings();
|
||||
return env('APP_ENV') == 'local'
|
||||
? $settings->test_endpoint_secret
|
||||
: $settings->endpoint_secret;
|
||||
}
|
||||
/**
|
||||
* @param $amount
|
||||
* @param $currencyCode
|
||||
* @param $payment_method
|
||||
* @return bool
|
||||
* @description check if the amount is higher than the minimum amount for the stripe gateway
|
||||
*/
|
||||
public static function checkPriceAmount($amount, $currencyCode, $payment_method)
|
||||
{
|
||||
$minimums = [
|
||||
"USD" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"AED" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 2
|
||||
],
|
||||
"AUD" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"BGN" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 1
|
||||
],
|
||||
"BRL" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"CAD" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"CHF" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"CZK" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 15
|
||||
],
|
||||
"DKK" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 2.5
|
||||
],
|
||||
"EUR" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"GBP" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.3
|
||||
],
|
||||
"HKD" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 4
|
||||
],
|
||||
"HRK" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"HUF" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 175
|
||||
],
|
||||
"INR" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"JPY" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"MXN" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 10
|
||||
],
|
||||
"MYR" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 2
|
||||
],
|
||||
"NOK" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 3
|
||||
],
|
||||
"NZD" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"PLN" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 2
|
||||
],
|
||||
"RON" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 2
|
||||
],
|
||||
"SEK" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 3
|
||||
],
|
||||
"SGD" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"THB" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 10
|
||||
]
|
||||
];
|
||||
return $amount >= $minimums[$currencyCode][$payment_method];
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Extensions\PaymentGateways\Stripe;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class StripeSettings extends Settings
|
||||
{
|
||||
|
||||
public bool $enabled = false;
|
||||
public ?string $secret_key;
|
||||
public ?string $endpoint_secret;
|
||||
public ?string $test_secret_key;
|
||||
public ?string $test_endpoint_secret;
|
||||
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'stripe';
|
||||
}
|
||||
|
||||
public static function encrypted(): array
|
||||
{
|
||||
return [
|
||||
"secret_key",
|
||||
"endpoint_secret",
|
||||
"test_secret_key",
|
||||
"test_endpoint_secret"
|
||||
];
|
||||
}
|
||||
|
||||
public static function getOptionInputData()
|
||||
{
|
||||
return [
|
||||
'category_icon' => 'fas fa-dollar-sign',
|
||||
'secret_key' => [
|
||||
'type' => 'string',
|
||||
'label' => 'Secret Key',
|
||||
'description' => 'The Secret Key of your Stripe App',
|
||||
],
|
||||
'endpoint_secret' => [
|
||||
'type' => 'string',
|
||||
'label' => 'Endpoint Secret',
|
||||
'description' => 'The Endpoint Secret of your Stripe App',
|
||||
],
|
||||
'test_secret_key' => [
|
||||
'type' => 'string',
|
||||
'label' => 'Test Secret Key',
|
||||
'description' => 'The Test Secret Key used when app_env = local',
|
||||
],
|
||||
'test_endpoint_secret' => [
|
||||
'type' => 'string',
|
||||
'label' => 'Test Endpoint Secret',
|
||||
'description' => 'The Test Endpoint Secret used when app_env = local',
|
||||
],
|
||||
'enabled' => [
|
||||
'type' => 'boolean',
|
||||
'label' => 'Enabled',
|
||||
'description' => 'Enable this payment gateway',
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
15
app/Extensions/PaymentGateways/Stripe/config.php
Normal file
15
app/Extensions/PaymentGateways/Stripe/config.php
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace App\Extensions\PaymentGateways\Stripe;
|
||||
|
||||
function getConfig()
|
||||
{
|
||||
return [
|
||||
"name" => "Stripe",
|
||||
"description" => "Stripe payment gateway",
|
||||
"RoutesIgnoreCsrf" => [
|
||||
"payment/StripeWebhooks",
|
||||
],
|
||||
"enabled" => config('SETTINGS::PAYMENTS:STRIPE:SECRET') && config('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET') || config('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET') && config('SETTINGS::PAYMENTS:STRIPE:TEST_SECRET') && env("APP_ENV") === "local",
|
||||
];
|
||||
}
|
373
app/Extensions/PaymentGateways/Stripe/index.php
Normal file
373
app/Extensions/PaymentGateways/Stripe/index.php
Normal file
|
@ -0,0 +1,373 @@
|
|||
<?php
|
||||
|
||||
use App\Events\PaymentEvent;
|
||||
use App\Events\UserUpdateCreditsEvent;
|
||||
use App\Models\PartnerDiscount;
|
||||
use App\Models\Payment;
|
||||
use App\Models\ShopProduct;
|
||||
use App\Models\User;
|
||||
use App\Notifications\ConfirmPaymentNotification;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Stripe\Exception\SignatureVerificationException;
|
||||
use Stripe\Stripe;
|
||||
use Stripe\StripeClient;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param ShopProduct $shopProduct
|
||||
*/
|
||||
function StripePay(Request $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
$shopProduct = ShopProduct::findOrFail($request->shopProduct);
|
||||
|
||||
// check if the price is valid for stripe
|
||||
if (!checkPriceAmount($shopProduct->getTotalPrice(), strtoupper($shopProduct->currency_code), 'stripe')) {
|
||||
Redirect::route('home')->with('error', __('The product you chose can\'t be purchased with this payment method. The total amount is too small. Please buy a bigger amount or try a different payment method.'))->send();
|
||||
return;
|
||||
}
|
||||
|
||||
$discount = PartnerDiscount::getDiscount();
|
||||
|
||||
|
||||
// create payment
|
||||
$payment = Payment::create([
|
||||
'user_id' => $user->id,
|
||||
'payment_id' => null,
|
||||
'payment_method' => 'stripe',
|
||||
'type' => $shopProduct->type,
|
||||
'status' => 'open',
|
||||
'amount' => $shopProduct->quantity,
|
||||
'price' => $shopProduct->price - ($shopProduct->price * $discount / 100),
|
||||
'tax_value' => $shopProduct->getTaxValue(),
|
||||
'total_price' => $shopProduct->getTotalPrice(),
|
||||
'tax_percent' => $shopProduct->getTaxPercent(),
|
||||
'currency_code' => $shopProduct->currency_code,
|
||||
'shop_item_product_id' => $shopProduct->id,
|
||||
]);
|
||||
|
||||
$stripeClient = getStripeClient();
|
||||
$request = $stripeClient->checkout->sessions->create([
|
||||
'line_items' => [
|
||||
[
|
||||
'price_data' => [
|
||||
'currency' => $shopProduct->currency_code,
|
||||
'product_data' => [
|
||||
'name' => $shopProduct->display . ($discount ? (' (' . __('Discount') . ' ' . $discount . '%)') : ''),
|
||||
'description' => $shopProduct->description,
|
||||
],
|
||||
'unit_amount_decimal' => round($shopProduct->getPriceAfterDiscount() * 100, 2),
|
||||
],
|
||||
'quantity' => 1,
|
||||
],
|
||||
[
|
||||
'price_data' => [
|
||||
'currency' => $shopProduct->currency_code,
|
||||
'product_data' => [
|
||||
'name' => __('Tax'),
|
||||
'description' => $shopProduct->getTaxPercent() . '%',
|
||||
],
|
||||
'unit_amount_decimal' => round($shopProduct->getTaxValue(), 2) * 100,
|
||||
],
|
||||
'quantity' => 1,
|
||||
],
|
||||
],
|
||||
|
||||
'mode' => 'payment',
|
||||
'payment_method_types' => str_getcsv(config('SETTINGS::PAYMENTS:STRIPE:METHODS')),
|
||||
'success_url' => route('payment.StripeSuccess', ['payment' => $payment->id]) . '&session_id={CHECKOUT_SESSION_ID}',
|
||||
'cancel_url' => route('payment.Cancel'),
|
||||
'payment_intent_data' => [
|
||||
'metadata' => [
|
||||
'payment_id' => $payment->id,
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
Redirect::to($request->url)->send();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*/
|
||||
function StripeSuccess(Request $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
$user = User::findOrFail($user->id);
|
||||
$payment = Payment::findOrFail($request->input('payment'));
|
||||
$shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
|
||||
|
||||
|
||||
Redirect::route('home')->with('success', 'Please wait for success')->send();
|
||||
|
||||
$stripeClient = getStripeClient();
|
||||
try {
|
||||
//get stripe data
|
||||
$paymentSession = $stripeClient->checkout->sessions->retrieve($request->input('session_id'));
|
||||
$paymentIntent = $stripeClient->paymentIntents->retrieve($paymentSession->payment_intent);
|
||||
|
||||
//get DB entry of this payment ID if existing
|
||||
$paymentDbEntry = Payment::where('payment_id', $paymentSession->payment_intent)->count();
|
||||
|
||||
// check if payment is 100% completed and payment does not exist in db already
|
||||
if ($paymentSession->status == 'complete' && $paymentIntent->status == 'succeeded' && $paymentDbEntry == 0) {
|
||||
|
||||
//update payment
|
||||
$payment->update([
|
||||
'payment_id' => $paymentSession->payment_intent,
|
||||
'status' => 'paid',
|
||||
]);
|
||||
|
||||
//payment notification
|
||||
$user->notify(new ConfirmPaymentNotification($payment));
|
||||
|
||||
event(new UserUpdateCreditsEvent($user));
|
||||
event(new PaymentEvent($user, $payment, $shopProduct));
|
||||
|
||||
//redirect back to home
|
||||
Redirect::route('home')->with('success', 'Payment successful')->send();
|
||||
} else {
|
||||
if ($paymentIntent->status == 'processing') {
|
||||
|
||||
//update payment
|
||||
$payment->update([
|
||||
'payment_id' => $paymentSession->payment_intent,
|
||||
'status' => 'processing',
|
||||
]);
|
||||
|
||||
event(new PaymentEvent($user, $payment, $shopProduct));
|
||||
|
||||
Redirect::route('home')->with('success', 'Your payment is being processed')->send();
|
||||
}
|
||||
|
||||
if ($paymentDbEntry == 0 && $paymentIntent->status != 'processing') {
|
||||
$stripeClient->paymentIntents->cancel($paymentIntent->id);
|
||||
|
||||
//redirect back to home
|
||||
Redirect::route('home')->with('info', __('Your payment has been canceled!'))->send();
|
||||
} else {
|
||||
abort(402);
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
if (env('APP_ENV') == 'local') {
|
||||
dd($e->getMessage());
|
||||
} else {
|
||||
abort(422);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*/
|
||||
function handleStripePaymentSuccessHook($paymentIntent)
|
||||
{
|
||||
try {
|
||||
$payment = Payment::where('id', $paymentIntent->metadata->payment_id)->with('user')->first();
|
||||
$user = User::where('id', $payment->user_id)->first();
|
||||
$shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id);
|
||||
|
||||
if ($paymentIntent->status == 'succeeded' && $payment->status == 'processing') {
|
||||
|
||||
//update payment db entry status
|
||||
$payment->update([
|
||||
'payment_id' => $payment->payment_id ?? $paymentIntent->id,
|
||||
'status' => 'paid'
|
||||
]);
|
||||
|
||||
//payment notification
|
||||
$user->notify(new ConfirmPaymentNotification($payment));
|
||||
event(new UserUpdateCreditsEvent($user));
|
||||
event(new PaymentEvent($user, $payment, $shopProduct));
|
||||
}
|
||||
|
||||
// return 200
|
||||
return response()->json(['success' => true], 200);
|
||||
} catch (Exception $ex) {
|
||||
abort(422);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*/
|
||||
function StripeWebhooks(Request $request)
|
||||
{
|
||||
Stripe::setApiKey(getStripeSecret());
|
||||
|
||||
try {
|
||||
$payload = @file_get_contents('php://input');
|
||||
$sig_header = $request->header('Stripe-Signature');
|
||||
$event = null;
|
||||
$event = \Stripe\Webhook::constructEvent(
|
||||
$payload,
|
||||
$sig_header,
|
||||
getStripeEndpointSecret()
|
||||
);
|
||||
} catch (\UnexpectedValueException $e) {
|
||||
// Invalid payload
|
||||
|
||||
abort(400);
|
||||
} catch (SignatureVerificationException $e) {
|
||||
// Invalid signature
|
||||
|
||||
abort(400);
|
||||
}
|
||||
|
||||
// Handle the event
|
||||
switch ($event->type) {
|
||||
case 'payment_intent.succeeded':
|
||||
$paymentIntent = $event->data->object; // contains a \Stripe\PaymentIntent
|
||||
handleStripePaymentSuccessHook($paymentIntent);
|
||||
break;
|
||||
default:
|
||||
echo 'Received unknown event type ' . $event->type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Stripe\StripeClient
|
||||
*/
|
||||
function getStripeClient()
|
||||
{
|
||||
return new StripeClient(getStripeSecret());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function getStripeSecret()
|
||||
{
|
||||
return env('APP_ENV') == 'local'
|
||||
? config('SETTINGS::PAYMENTS:STRIPE:TEST_SECRET')
|
||||
: config('SETTINGS::PAYMENTS:STRIPE:SECRET');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function getStripeEndpointSecret()
|
||||
{
|
||||
return env('APP_ENV') == 'local'
|
||||
? config('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET')
|
||||
: config('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET');
|
||||
}
|
||||
/**
|
||||
* @param $amount
|
||||
* @param $currencyCode
|
||||
* @param $payment_method
|
||||
* @return bool
|
||||
* @description check if the amount is higher than the minimum amount for the stripe gateway
|
||||
*/
|
||||
function checkPriceAmount($amount, $currencyCode, $payment_method)
|
||||
{
|
||||
$minimums = [
|
||||
"USD" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"AED" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 2
|
||||
],
|
||||
"AUD" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"BGN" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 1
|
||||
],
|
||||
"BRL" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"CAD" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"CHF" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"CZK" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 15
|
||||
],
|
||||
"DKK" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 2.5
|
||||
],
|
||||
"EUR" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"GBP" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.3
|
||||
],
|
||||
"HKD" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 4
|
||||
],
|
||||
"HRK" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"HUF" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 175
|
||||
],
|
||||
"INR" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"JPY" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"MXN" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 10
|
||||
],
|
||||
"MYR" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 2
|
||||
],
|
||||
"NOK" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 3
|
||||
],
|
||||
"NZD" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"PLN" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 2
|
||||
],
|
||||
"RON" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 2
|
||||
],
|
||||
"SEK" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 3
|
||||
],
|
||||
"SGD" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 0.5
|
||||
],
|
||||
"THB" => [
|
||||
"paypal" => 0,
|
||||
"stripe" => 10
|
||||
]
|
||||
];
|
||||
return $amount >= $minimums[$currencyCode][$payment_method];
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CreateStripeSettings extends SettingsMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$table_exists = DB::table('settings_old')->exists();
|
||||
|
||||
$this->migrator->addEncrypted('stripe.secret_key', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:SECRET') : null);
|
||||
$this->migrator->addEncrypted('stripe.endpoint_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET') : null);
|
||||
$this->migrator->addEncrypted('stripe.test_secret_key', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:TEST_SECRET') : null);
|
||||
$this->migrator->addEncrypted('stripe.test_endpoint_secret', $table_exists ? $this->getOldValue('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET') : null);
|
||||
$this->migrator->add('stripe.enabled', false);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::table('settings_old')->insert([
|
||||
[
|
||||
'key' => 'SETTINGS::PAYMENTS:STRIPE:SECRET',
|
||||
'value' => $this->getNewValue('secret_key'),
|
||||
'type' => 'string',
|
||||
'description' => 'The Secret Key of your Stripe App'
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET',
|
||||
'value' => $this->getNewValue('endpoint_secret'),
|
||||
'type' => 'string',
|
||||
'description' => 'The Endpoint Secret of your Stripe App'
|
||||
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::PAYMENTS:STRIPE:TEST_SECRET',
|
||||
'value' => $this->getNewValue('test_secret_key'),
|
||||
'type' => 'string',
|
||||
'description' => 'The Test Secret Key of your Stripe App'
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET',
|
||||
'value' => $this->getNewValue('test_endpoint_secret'),
|
||||
'type' => 'string',
|
||||
'description' => 'The Test Endpoint Secret of your Stripe App'
|
||||
]
|
||||
]);
|
||||
|
||||
$this->migrator->delete('stripe.secret_key');
|
||||
$this->migrator->delete('stripe.endpoint_secret');
|
||||
$this->migrator->delete('stripe.enabled');
|
||||
$this->migrator->delete('stripe.test_secret_key');
|
||||
$this->migrator->delete('stripe.test_endpoint_secret');
|
||||
}
|
||||
|
||||
public function getNewValue(string $name)
|
||||
{
|
||||
$new_value = DB::table('settings')->where([['group', '=', 'stripe'], ['name', '=', $name]])->get(['payload'])->first();
|
||||
|
||||
// Some keys returns '""' as a value.
|
||||
if ($new_value->payload === '""') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// remove the quotes from the string
|
||||
if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
|
||||
return substr($new_value->payload, 1, -1);
|
||||
}
|
||||
|
||||
return $new_value->payload;
|
||||
}
|
||||
|
||||
public function getOldValue(string $key)
|
||||
{
|
||||
// Always get the first value of the key.
|
||||
$old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
|
||||
|
||||
// Handle the old values to return without it being a string in all cases.
|
||||
if ($old_value->type === "string" || $old_value->type === "text") {
|
||||
if (is_null($old_value->value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Some values have the type string, but their values are boolean.
|
||||
if ($old_value->value === "false" || $old_value->value === "true") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return $old_value->value;
|
||||
}
|
||||
|
||||
if ($old_value->type === "boolean") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_INT);
|
||||
}
|
||||
}
|
|
@ -1,17 +1,17 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use App\Extensions\PaymentGateways\Stripe\StripeExtension;
|
||||
|
||||
include_once(__DIR__ . '/index.php');
|
||||
Route::middleware(['web', 'auth'])->group(function () {
|
||||
Route::get('payment/StripePay/{shopProduct}', function () {
|
||||
StripeExtension::StripePay(request());
|
||||
StripePay(request());
|
||||
})->name('payment.StripePay');
|
||||
|
||||
Route::get(
|
||||
'payment/StripeSuccess',
|
||||
function () {
|
||||
StripeExtension::StripeSuccess(request());
|
||||
StripeSuccess(request());
|
||||
}
|
||||
)->name('payment.StripeSuccess');
|
||||
});
|
||||
|
@ -19,5 +19,5 @@ Route::middleware(['web', 'auth'])->group(function () {
|
|||
|
||||
// Stripe WebhookRoute -> validation in Route Handler
|
||||
Route::post('payment/StripeWebhooks', function () {
|
||||
StripeExtension::StripeWebhooks(request());
|
||||
StripeWebhooks(request());
|
||||
})->name('payment.StripeWebhooks');
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Helpers;
|
||||
|
||||
// create a abstract class for the extension that will contain all the methods that will be used in the extension
|
||||
abstract class AbstractExtension
|
||||
{
|
||||
abstract public static function getConfig(): array;
|
||||
}
|
|
@ -2,14 +2,65 @@
|
|||
|
||||
namespace App\Helpers;
|
||||
|
||||
/**
|
||||
* Summary of ExtensionHelper
|
||||
*/
|
||||
class ExtensionHelper
|
||||
{
|
||||
/**
|
||||
* Get a config of an extension by its name
|
||||
* @param string $extensionName
|
||||
* @param string $configname
|
||||
*/
|
||||
public static function getExtensionConfig(string $extensionName, string $configname)
|
||||
{
|
||||
$extensions = ExtensionHelper::getAllExtensions();
|
||||
|
||||
// call the getConfig function of the config file of the extension like that
|
||||
// call_user_func("App\\Extensions\\PaymentGateways\\Stripe" . "\\getConfig");
|
||||
foreach ($extensions as $extension) {
|
||||
if (!(basename($extension) == $extensionName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$configFile = $extension . '/config.php';
|
||||
if (file_exists($configFile)) {
|
||||
include_once $configFile;
|
||||
$config = call_user_func('App\\Extensions\\' . basename(dirname($extension)) . '\\' . basename($extension) . "\\getConfig");
|
||||
}
|
||||
|
||||
|
||||
if (isset($config[$configname])) {
|
||||
return $config[$configname];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function getAllCsrfIgnoredRoutes()
|
||||
{
|
||||
$extensions = ExtensionHelper::getAllExtensions();
|
||||
|
||||
$routes = [];
|
||||
foreach ($extensions as $extension) {
|
||||
$configFile = $extension . '/config.php';
|
||||
if (file_exists($configFile)) {
|
||||
include_once $configFile;
|
||||
$config = call_user_func('App\\Extensions\\' . basename(dirname($extension)) . '\\' . basename($extension) . "\\getConfig");
|
||||
}
|
||||
|
||||
if (isset($config['RoutesIgnoreCsrf'])) {
|
||||
$routes = array_merge($routes, $config['RoutesIgnoreCsrf']);
|
||||
}
|
||||
|
||||
// map over the routes and add the extension name as prefix
|
||||
$result = array_map(fn ($item) => "extensions/{$item}", $routes);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all extensions
|
||||
* @return array array of all extensions e.g. ["App\Extensions\PayPal", "App\Extensions\Stripe"]
|
||||
* @return array
|
||||
*/
|
||||
public static function getAllExtensions()
|
||||
{
|
||||
|
@ -18,195 +69,14 @@ class ExtensionHelper
|
|||
foreach ($extensionNamespaces as $extensionNamespace) {
|
||||
$extensions = array_merge($extensions, glob($extensionNamespace . '/*', GLOB_ONLYDIR));
|
||||
}
|
||||
// remove base path from every extension but keep app/Extensions/...
|
||||
$extensions = array_map(fn ($item) => str_replace('/', '\\', str_replace(app_path() . '/', 'App/', $item)), $extensions);
|
||||
|
||||
return $extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all extensions by namespace
|
||||
* @param string $namespace case sensitive namespace of the extension e.g. PaymentGateways
|
||||
* @return array array of all extensions e.g. ["App\Extensions\PayPal", "App\Extensions\Stripe"]
|
||||
*/
|
||||
public static function getAllExtensionsByNamespace(string $namespace)
|
||||
{
|
||||
$extensions = glob(app_path() . '/Extensions/' . $namespace . '/*', GLOB_ONLYDIR);
|
||||
// remove base path from every extension but keep app/Extensions/...
|
||||
$extensions = array_map(fn ($item) => str_replace('/', '\\', str_replace(app_path() . '/', 'App/', $item)), $extensions);
|
||||
|
||||
return $extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an extension by its name
|
||||
* @param string $extensionName case sensitive name of the extension e.g. PayPal
|
||||
* @return string|null the path of the extension e.g. App\Extensions\PayPal
|
||||
*/
|
||||
public static function getExtension(string $extensionName)
|
||||
{
|
||||
$extensions = self::getAllExtensions();
|
||||
// filter the extensions by the extension name
|
||||
$extensions = array_filter($extensions, fn ($item) => basename($item) == $extensionName);
|
||||
|
||||
// return the only extension
|
||||
return array_shift($extensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all extension classes
|
||||
* @return array array of all extension classes e.g. ["App\Extensions\PayPal\PayPalExtension", "App\Extensions\Stripe\StripeExtension"]
|
||||
*/
|
||||
public static function getAllExtensionClasses()
|
||||
{
|
||||
$extensions = self::getAllExtensions();
|
||||
// add the ExtensionClass to the end of the namespace
|
||||
$extensions = array_map(fn ($item) => $item . '\\' . basename($item) . 'Extension', $extensions);
|
||||
// filter out non existing extension classes
|
||||
$extensions = array_filter($extensions, fn ($item) => class_exists($item));
|
||||
|
||||
return $extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all extension classes by namespace
|
||||
* @param string $namespace case sensitive namespace of the extension e.g. PaymentGateways
|
||||
* @return array array of all extension classes e.g. ["App\Extensions\PayPal\PayPalExtension", "App\Extensions\Stripe\StripeExtension"]
|
||||
*/
|
||||
public static function getAllExtensionClassesByNamespace(string $namespace)
|
||||
{
|
||||
$extensions = self::getAllExtensionsByNamespace($namespace);
|
||||
// add the ExtensionClass to the end of the namespace
|
||||
$extensions = array_map(fn ($item) => $item . '\\' . basename($item) . 'Extension', $extensions);
|
||||
// filter out non existing extension classes
|
||||
$extensions = array_filter($extensions, fn ($item) => class_exists($item));
|
||||
|
||||
return $extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class of an extension by its name
|
||||
* @param string $extensionName case sensitive name of the extension e.g. PayPal
|
||||
* @return string|null the class name of the extension e.g. App\Extensions\PayPal\PayPalExtension
|
||||
*/
|
||||
public static function getExtensionClass(string $extensionName)
|
||||
{
|
||||
$extensions = self::getAllExtensions();
|
||||
|
||||
foreach ($extensions as $extension) {
|
||||
if (!(basename($extension) == $extensionName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$extensionClass = $extension . '\\' . $extensionName . 'Extension';
|
||||
return $extensionClass;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get a config of an extension by its name
|
||||
* @param string $extensionName
|
||||
* @param string $configname
|
||||
*/
|
||||
public static function getExtensionConfig(string $extensionName, string $configname)
|
||||
{
|
||||
|
||||
$extension = self::getExtensionClass($extensionName);
|
||||
|
||||
$config = $extension::getConfig();
|
||||
|
||||
|
||||
|
||||
if (isset($config[$configname])) {
|
||||
return $config[$configname];
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function getAllCsrfIgnoredRoutes()
|
||||
{
|
||||
$extensions = self::getAllExtensionClasses();
|
||||
|
||||
$routes = [];
|
||||
|
||||
foreach ($extensions as $extension) {
|
||||
$config = $extension::getConfig();
|
||||
|
||||
if (isset($config['RoutesIgnoreCsrf'])) {
|
||||
$routes = array_merge($routes, $config['RoutesIgnoreCsrf']);
|
||||
}
|
||||
}
|
||||
// map over the routes and add the extension name as prefix
|
||||
$result = array_map(fn ($item) => "extensions/{$item}", $routes);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of getAllExtensionMigrations
|
||||
* @return array of all migration paths look like: app/Extensions/ExtensionNamespace/ExtensionName/migrations/
|
||||
*/
|
||||
public static function getAllExtensionMigrations()
|
||||
{
|
||||
$extensions = self::getAllExtensions();
|
||||
// Transform the extensions to a path
|
||||
$extensions = array_map(fn ($item) => self::extensionNameToPath($item), $extensions);
|
||||
|
||||
// get all migration directories of the extensions and return them as array
|
||||
$migrations = [];
|
||||
foreach ($extensions as $extension) {
|
||||
$migrationDir = $extension . '/migrations';
|
||||
if (file_exists($migrationDir)) {
|
||||
$migrations[] = $migrationDir;
|
||||
}
|
||||
}
|
||||
|
||||
return $migrations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of getAllExtensionSettings
|
||||
* @return array of all setting classes look like: App\Extensions\PaymentGateways\PayPal\PayPalSettings
|
||||
*/
|
||||
public static function getAllExtensionSettingsClasses()
|
||||
{
|
||||
$extensions = self::getAllExtensions();
|
||||
|
||||
$settings = [];
|
||||
foreach ($extensions as $extension) {
|
||||
|
||||
$extensionName = basename($extension);
|
||||
$settingsClass = $extension . '\\' . $extensionName . 'Settings';
|
||||
if (class_exists($settingsClass)) {
|
||||
$settings[] = $settingsClass;
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
public static function getExtensionSettings(string $extensionName)
|
||||
{
|
||||
$extension = self::getExtension($extensionName);
|
||||
$settingClass = $extension . '\\' . $extensionName . 'Settings';
|
||||
|
||||
if (class_exists($settingClass)) {
|
||||
return new $settingClass();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a extension name to a path
|
||||
* @param string $extensionName e.g. App\Extensions\PaymentGateways\PayPal
|
||||
* @return string e.g. C:\xampp\htdocs\laravel\app/Extensions/PaymentGateways/PayPal
|
||||
*/
|
||||
private static function extensionNameToPath(string $extensionName)
|
||||
{
|
||||
return app_path() . '/' . str_replace('\\', '/', str_replace('App\\', '', $extensionName));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ namespace App\Http\Controllers\Admin;
|
|||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\ApplicationApi;
|
||||
use App\Settings\LocaleSettings;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
|
@ -21,11 +20,9 @@ class ApplicationApiController extends Controller
|
|||
*
|
||||
* @return Application|Factory|View|Response
|
||||
*/
|
||||
public function index(LocaleSettings $locale_settings)
|
||||
public function index()
|
||||
{
|
||||
return view('admin.api.index', [
|
||||
'locale_datatables' => $locale_settings->datatables
|
||||
]);
|
||||
return view('admin.api.index');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,7 +15,7 @@ class InvoiceController extends Controller
|
|||
$zip = new ZipArchive;
|
||||
$zip_safe_path = storage_path('invoices.zip');
|
||||
$res = $zip->open($zip_safe_path, ZipArchive::CREATE | ZipArchive::OVERWRITE);
|
||||
$result = $this->rglob(storage_path('app/invoice/*'));
|
||||
$result = $this::rglob(storage_path('app/invoice/*'));
|
||||
if ($res === true) {
|
||||
$zip->addFromString('1. Info.txt', __('Created at').' '.now()->format('d.m.Y'));
|
||||
foreach ($result as $file) {
|
||||
|
@ -38,7 +38,7 @@ class InvoiceController extends Controller
|
|||
{
|
||||
$files = glob($pattern, $flags);
|
||||
foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
|
||||
$files = array_merge($files, $this->rglob($dir.'/'.basename($pattern), $flags));
|
||||
$files = array_merge($files, $this::rglob($dir.'/'.basename($pattern), $flags));
|
||||
}
|
||||
|
||||
return $files;
|
||||
|
|
|
@ -2,14 +2,12 @@
|
|||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Classes\PterodactylClient;
|
||||
use App\Settings\PterodactylSettings;
|
||||
use App\Settings\GeneralSettings;
|
||||
use App\Classes\Pterodactyl;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Pterodactyl\Egg;
|
||||
use App\Models\Pterodactyl\Location;
|
||||
use App\Models\Pterodactyl\Nest;
|
||||
use App\Models\Pterodactyl\Node;
|
||||
use App\Models\Egg;
|
||||
use App\Models\Location;
|
||||
use App\Models\Nest;
|
||||
use App\Models\Node;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Product;
|
||||
use App\Models\Server;
|
||||
|
@ -21,14 +19,7 @@ class OverViewController extends Controller
|
|||
{
|
||||
public const TTL = 86400;
|
||||
|
||||
private $pterodactyl;
|
||||
|
||||
public function __construct(PterodactylSettings $ptero_settings)
|
||||
{
|
||||
$this->pterodactyl = new PterodactylClient($ptero_settings);
|
||||
}
|
||||
|
||||
public function index(GeneralSettings $general_settings)
|
||||
public function index()
|
||||
{
|
||||
//Get counters
|
||||
$counters = collect();
|
||||
|
@ -143,7 +134,7 @@ class OverViewController extends Controller
|
|||
|
||||
//Get node information and prepare collection
|
||||
$pteroNodeIds = [];
|
||||
foreach ($this->pterodactyl->getNodes() as $pteroNode) {
|
||||
foreach (Pterodactyl::getNodes() as $pteroNode) {
|
||||
array_push($pteroNodeIds, $pteroNode['attributes']['id']);
|
||||
}
|
||||
$nodes = collect();
|
||||
|
@ -154,7 +145,7 @@ class OverViewController extends Controller
|
|||
} //Check if node exists on pterodactyl too, if not, skip
|
||||
$nodes->put($nodeId, collect());
|
||||
$nodes[$nodeId]->name = $DBnode['name'];
|
||||
$pteroNode = $this->pterodactyl->getNode($nodeId);
|
||||
$pteroNode = Pterodactyl::getNode($nodeId);
|
||||
$nodes[$nodeId]->usagePercent = round(max($pteroNode['allocated_resources']['memory'] / ($pteroNode['memory'] * ($pteroNode['memory_overallocate'] + 100) / 100), $pteroNode['allocated_resources']['disk'] / ($pteroNode['disk'] * ($pteroNode['disk_overallocate'] + 100) / 100)) * 100, 2);
|
||||
$counters['totalUsagePercent'] += $nodes[$nodeId]->usagePercent;
|
||||
|
||||
|
@ -165,7 +156,7 @@ class OverViewController extends Controller
|
|||
}
|
||||
$counters['totalUsagePercent'] = ($DBnodes->count()) ? round($counters['totalUsagePercent'] / $DBnodes->count(), 2) : 0;
|
||||
|
||||
foreach ($this->pterodactyl->getServers() as $server) { //gets all servers from Pterodactyl and calculates total of credit usage for each node separately + total
|
||||
foreach (Pterodactyl::getServers() as $server) { //gets all servers from Pterodactyl and calculates total of credit usage for each node separately + total
|
||||
$nodeId = $server['attributes']['node'];
|
||||
|
||||
if ($CPServer = Server::query()->where('pterodactyl_id', $server['attributes']['id'])->first()) {
|
||||
|
@ -216,7 +207,6 @@ class OverViewController extends Controller
|
|||
'deletedNodesPresent' => ($DBnodes->count() != count($pteroNodeIds)) ? true : false,
|
||||
'perPageLimit' => ($counters['servers']->total != Server::query()->count()) ? true : false,
|
||||
'tickets' => $tickets,
|
||||
'credits_display_name' => $general_settings->credits_display_name
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,17 +5,13 @@ namespace App\Http\Controllers\Admin;
|
|||
use App\Http\Controllers\Controller;
|
||||
use App\Models\PartnerDiscount;
|
||||
use App\Models\User;
|
||||
use App\Settings\LocaleSettings;
|
||||
use App\Settings\ReferralSettings;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class PartnerController extends Controller
|
||||
{
|
||||
public function index(LocaleSettings $locale_settings)
|
||||
public function index()
|
||||
{
|
||||
return view('admin.partners.index', [
|
||||
'locale_datatables' => $locale_settings->datatables
|
||||
]);
|
||||
return view('admin.partners.index');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -121,19 +117,19 @@ class PartnerController extends Controller
|
|||
';
|
||||
})
|
||||
->addColumn('user', function (PartnerDiscount $partner) {
|
||||
return ($user = User::where('id', $partner->user_id)->first()) ? '<a href="'.route('admin.users.show', $partner->user_id) . '">' . $user->name . '</a>' : __('Unknown user');
|
||||
return ($user = User::where('id', $partner->user_id)->first()) ? '<a href="'.route('admin.users.show', $partner->user_id).'">'.$user->name.'</a>' : __('Unknown user');
|
||||
})
|
||||
->editColumn('created_at', function (PartnerDiscount $partner) {
|
||||
return $partner->created_at ? $partner->created_at->diffForHumans() : '';
|
||||
})
|
||||
->editColumn('partner_discount', function (PartnerDiscount $partner) {
|
||||
return $partner->partner_discount ? $partner->partner_discount . '%' : '0%';
|
||||
return $partner->partner_discount ? $partner->partner_discount.'%' : '0%';
|
||||
})
|
||||
->editColumn('registered_user_discount', function (PartnerDiscount $partner) {
|
||||
return $partner->registered_user_discount ? $partner->registered_user_discount . '%' : '0%';
|
||||
return $partner->registered_user_discount ? $partner->registered_user_discount.'%' : '0%';
|
||||
})
|
||||
->editColumn('referral_system_commission', function (PartnerDiscount $partner, ReferralSettings $referral_settings) {
|
||||
return $partner->referral_system_commission >= 0 ? $partner->referral_system_commission . '%' : __('Default') . ' ('.$referral_settings->percentage . '%)';
|
||||
->editColumn('referral_system_commission', function (PartnerDiscount $partner) {
|
||||
return $partner->referral_system_commission >= 0 ? $partner->referral_system_commission.'%' : __('Default').' ('.config('SETTINGS::REFERRAL:PERCENTAGE').'%)';
|
||||
})
|
||||
->rawColumns(['user', 'actions'])
|
||||
->make();
|
||||
|
|
|
@ -18,19 +18,17 @@ use Illuminate\Http\RedirectResponse;
|
|||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Helpers\ExtensionHelper;
|
||||
use App\Settings\GeneralSettings;
|
||||
use App\Settings\LocaleSettings;
|
||||
|
||||
|
||||
class PaymentController extends Controller
|
||||
{
|
||||
/**
|
||||
* @return Application|Factory|View
|
||||
*/
|
||||
public function index(LocaleSettings $locale_settings)
|
||||
public function index()
|
||||
{
|
||||
return view('admin.payments.index')->with([
|
||||
'payments' => Payment::paginate(15),
|
||||
'locale_datatables' => $locale_settings->datatables
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -39,7 +37,7 @@ class PaymentController extends Controller
|
|||
* @param ShopProduct $shopProduct
|
||||
* @return Application|Factory|View
|
||||
*/
|
||||
public function checkOut(ShopProduct $shopProduct, GeneralSettings $general_settings)
|
||||
public function checkOut(ShopProduct $shopProduct)
|
||||
{
|
||||
$discount = PartnerDiscount::getDiscount();
|
||||
$price = $shopProduct->price - ($shopProduct->price * $discount / 100);
|
||||
|
@ -51,10 +49,7 @@ class PaymentController extends Controller
|
|||
// build a paymentgateways array that contains the routes for the payment gateways and the image path for the payment gateway which lays in public/images/Extensions/PaymentGateways with the extensionname in lowercase
|
||||
foreach ($extensions as $extension) {
|
||||
$extensionName = basename($extension);
|
||||
|
||||
$extensionSettings = ExtensionHelper::getExtensionSettings($extensionName);
|
||||
if ($extensionSettings->enabled == false) continue;
|
||||
|
||||
if (!ExtensionHelper::getExtensionConfig($extensionName, 'enabled')) continue; // skip if not enabled
|
||||
|
||||
$payment = new \stdClass();
|
||||
$payment->name = ExtensionHelper::getExtensionConfig($extensionName, 'name');
|
||||
|
@ -63,6 +58,11 @@ class PaymentController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return view('store.checkout')->with([
|
||||
'product' => $shopProduct,
|
||||
'discountpercent' => $discount,
|
||||
|
@ -73,7 +73,6 @@ class PaymentController extends Controller
|
|||
'total' => $shopProduct->getTotalPrice(),
|
||||
'paymentGateways' => $paymentGateways,
|
||||
'productIsFree' => $price <= 0,
|
||||
'credits_display_name' => $general_settings->credits_display_name
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,12 +3,9 @@
|
|||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Pterodactyl\Location;
|
||||
use App\Models\Pterodactyl\Nest;
|
||||
use App\Models\Location;
|
||||
use App\Models\Nest;
|
||||
use App\Models\Product;
|
||||
use App\Settings\GeneralSettings;
|
||||
use App\Settings\LocaleSettings;
|
||||
use App\Settings\UserSettings;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
|
@ -24,11 +21,9 @@ class ProductController extends Controller
|
|||
*
|
||||
* @return Application|Factory|View
|
||||
*/
|
||||
public function index(LocaleSettings $locale_settings)
|
||||
public function index()
|
||||
{
|
||||
return view('admin.products.index', [
|
||||
'locale_datatables' => $locale_settings->datatables
|
||||
]);
|
||||
return view('admin.products.index');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,16 +31,15 @@ class ProductController extends Controller
|
|||
*
|
||||
* @return Application|Factory|View
|
||||
*/
|
||||
public function create(GeneralSettings $general_settings)
|
||||
public function create()
|
||||
{
|
||||
return view('admin.products.create', [
|
||||
'locations' => Location::with('nodes')->get(),
|
||||
'nests' => Nest::with('eggs')->get(),
|
||||
'credits_display_name' => $general_settings->credits_display_name
|
||||
]);
|
||||
}
|
||||
|
||||
public function clone(Product $product)
|
||||
public function clone(Request $request, Product $product)
|
||||
{
|
||||
return view('admin.products.create', [
|
||||
'product' => $product,
|
||||
|
@ -96,12 +90,11 @@ class ProductController extends Controller
|
|||
* @param Product $product
|
||||
* @return Application|Factory|View
|
||||
*/
|
||||
public function show(Product $product, UserSettings $user_settings, GeneralSettings $general_settings)
|
||||
public function show(Product $product)
|
||||
{
|
||||
return view('admin.products.show', [
|
||||
'product' => $product,
|
||||
'minimum_credits' => $user_settings->min_credits_to_make_server,
|
||||
'credits_display_name' => $general_settings->credits_display_name
|
||||
'minimum_credits' => config('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER'),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -111,13 +104,12 @@ class ProductController extends Controller
|
|||
* @param Product $product
|
||||
* @return Application|Factory|View
|
||||
*/
|
||||
public function edit(Product $product, GeneralSettings $general_settings)
|
||||
public function edit(Product $product)
|
||||
{
|
||||
return view('admin.products.edit', [
|
||||
'product' => $product,
|
||||
'locations' => Location::with('nodes')->get(),
|
||||
'nests' => Nest::with('eggs')->get(),
|
||||
'credits_display_name' => $general_settings->credits_display_name
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -165,7 +157,7 @@ class ProductController extends Controller
|
|||
* @param Product $product
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function disable(Product $product)
|
||||
public function disable(Request $request, Product $product)
|
||||
{
|
||||
$product->update(['disabled' => ! $product->disabled]);
|
||||
|
||||
|
@ -198,6 +190,7 @@ class ProductController extends Controller
|
|||
public function dataTable()
|
||||
{
|
||||
$query = Product::with(['servers']);
|
||||
|
||||
return datatables($query)
|
||||
->addColumn('actions', function (Product $product) {
|
||||
return '
|
||||
|
@ -226,18 +219,18 @@ class ProductController extends Controller
|
|||
$checked = $product->disabled == false ? 'checked' : '';
|
||||
|
||||
return '
|
||||
<form class="d-inline" onsubmit="return submitResult();" method="post" action="'.route('admin.products.disable', $product->id).'">
|
||||
'.csrf_field().'
|
||||
'.method_field('PATCH').'
|
||||
<div class="custom-control custom-switch">
|
||||
<input '.$checked.' name="disabled" onchange="this.form.submit()" type="checkbox" class="custom-control-input" id="switch'.$product->id.'">
|
||||
<label class="custom-control-label" for="switch'.$product->id.'"></label>
|
||||
</div>
|
||||
</form>
|
||||
<form class="d-inline" onsubmit="return submitResult();" method="post" action="'.route('admin.products.disable', $product->id).'">
|
||||
'.csrf_field().'
|
||||
'.method_field('PATCH').'
|
||||
<div class="custom-control custom-switch">
|
||||
<input '.$checked.' name="disabled" onchange="this.form.submit()" type="checkbox" class="custom-control-input" id="switch'.$product->id.'">
|
||||
<label class="custom-control-label" for="switch'.$product->id.'"></label>
|
||||
</div>
|
||||
</form>
|
||||
';
|
||||
})
|
||||
->editColumn('minimum_credits', function (Product $product, UserSettings $user_settings) {
|
||||
return $product->minimum_credits==-1 ? $user_settings->min_credits_to_make_server : $product->minimum_credits;
|
||||
->editColumn('minimum_credits', function (Product $product) {
|
||||
return $product->minimum_credits==-1 ? config('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER') : $product->minimum_credits;
|
||||
})
|
||||
->editColumn('created_at', function (Product $product) {
|
||||
return $product->created_at ? $product->created_at->diffForHumans() : '';
|
||||
|
|
|
@ -2,12 +2,10 @@
|
|||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Classes\Pterodactyl;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Server;
|
||||
use App\Models\User;
|
||||
use App\Settings\LocaleSettings;
|
||||
use App\Settings\PterodactylSettings;
|
||||
use App\Classes\PterodactylClient;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
|
@ -20,23 +18,14 @@ use Illuminate\Support\Facades\Log;
|
|||
|
||||
class ServerController extends Controller
|
||||
{
|
||||
private $pterodactyl;
|
||||
|
||||
public function __construct(PterodactylSettings $ptero_settings)
|
||||
{
|
||||
$this->pterodactyl = new PterodactylClient($ptero_settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return Application|Factory|View|Response
|
||||
*/
|
||||
public function index(LocaleSettings $locale_settings)
|
||||
public function index()
|
||||
{
|
||||
return view('admin.servers.index', [
|
||||
'locale_datatables' => $locale_settings->datatables
|
||||
]);
|
||||
return view('admin.servers.index');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,7 +65,7 @@ class ServerController extends Controller
|
|||
|
||||
// try to update the owner on pterodactyl
|
||||
try {
|
||||
$response = $this->pterodactyl->updateServerOwner($server, $user->pterodactyl_id);
|
||||
$response = Pterodactyl::updateServerOwner($server, $user->pterodactyl_id);
|
||||
if ($response->getStatusCode() != 200) {
|
||||
return redirect()->back()->with('error', 'Failed to update server owner on pterodactyl');
|
||||
}
|
||||
|
@ -129,6 +118,7 @@ class ServerController extends Controller
|
|||
|
||||
public function syncServers()
|
||||
{
|
||||
$pteroServers = Pterodactyl::getServers();
|
||||
$CPServers = Server::get();
|
||||
|
||||
$CPIDArray = [];
|
||||
|
@ -139,7 +129,7 @@ class ServerController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
foreach ($this->pterodactyl->getServers() as $server) { //go thru all ptero servers, if server exists, change value to true in array.
|
||||
foreach ($pteroServers as $server) { //go thru all ptero servers, if server exists, change value to true in array.
|
||||
if (isset($CPIDArray[$server['attributes']['id']])) {
|
||||
$CPIDArray[$server['attributes']['id']] = true;
|
||||
|
||||
|
@ -159,7 +149,7 @@ class ServerController extends Controller
|
|||
}, ARRAY_FILTER_USE_BOTH); //Array of servers, that dont exist on ptero (value == false)
|
||||
$deleteCount = 0;
|
||||
foreach ($filteredArray as $key => $CPID) { //delete servers that dont exist on ptero anymore
|
||||
if (!$this->pterodactyl->getServerAttributes($key, true)) {
|
||||
if (!Pterodactyl::getServerAttributes($key, true)) {
|
||||
$deleteCount++;
|
||||
}
|
||||
}
|
||||
|
@ -226,8 +216,8 @@ class ServerController extends Controller
|
|||
->editColumn('suspended', function (Server $server) {
|
||||
return $server->suspended ? $server->suspended->diffForHumans() : '';
|
||||
})
|
||||
->editColumn('name', function (Server $server, PterodactylSettings $ptero_settings) {
|
||||
return '<a class="text-info" target="_blank" href="' . $ptero_settings->panel_url . '/admin/servers/view/' . $server->pterodactyl_id . '">' . strip_tags($server->name) . '</a>';
|
||||
->editColumn('name', function (Server $server) {
|
||||
return '<a class="text-info" target="_blank" href="' . config('SETTINGS::SYSTEM:PTERODACTYL:URL') . '/admin/servers/view/' . $server->pterodactyl_id . '">' . strip_tags($server->name) . '</a>';
|
||||
})
|
||||
->rawColumns(['user', 'actions', 'status', 'name'])
|
||||
->make();
|
||||
|
|
|
@ -2,15 +2,11 @@
|
|||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Helpers\ExtensionHelper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Qirolab\Theme\Theme;
|
||||
|
||||
class SettingsController extends Controller
|
||||
|
@ -23,109 +19,37 @@ class SettingsController extends Controller
|
|||
public function index()
|
||||
{
|
||||
|
||||
// get all other settings in app/Settings directory
|
||||
// group items by file name like $categories
|
||||
$settings = collect();
|
||||
$settings_classes = [];
|
||||
|
||||
// get all app settings
|
||||
$app_settings = scandir(app_path('Settings'));
|
||||
$app_settings = array_diff($app_settings, ['.', '..']);
|
||||
// append App\Settings to class name
|
||||
foreach ($app_settings as $app_setting) {
|
||||
$settings_classes[] = 'App\\Settings\\' . str_replace('.php', '', $app_setting);
|
||||
}
|
||||
// get all extension settings
|
||||
$settings_files = array_merge($settings_classes, ExtensionHelper::getAllExtensionSettingsClasses());
|
||||
|
||||
|
||||
foreach ($settings_files as $file) {
|
||||
|
||||
$className = $file;
|
||||
// instantiate the class and call toArray method to get all options
|
||||
$options = (new $className())->toArray();
|
||||
|
||||
// call getOptionInputData method to get all options
|
||||
if (method_exists($className, 'getOptionInputData')) {
|
||||
$optionInputData = $className::getOptionInputData();
|
||||
} else {
|
||||
$optionInputData = [];
|
||||
}
|
||||
|
||||
// collect all option input data
|
||||
$optionsData = [];
|
||||
foreach ($options as $key => $value) {
|
||||
$optionsData[$key] = [
|
||||
'value' => $value,
|
||||
'label' => $optionInputData[$key]['label'] ?? ucwords(str_replace('_', ' ', $key)),
|
||||
'type' => $optionInputData[$key]['type'] ?? 'string',
|
||||
'description' => $optionInputData[$key]['description'] ?? '',
|
||||
'options' => $optionInputData[$key]['options'] ?? [],
|
||||
];
|
||||
}
|
||||
|
||||
// collect category icon if available
|
||||
if (isset($optionInputData['category_icon'])) {
|
||||
$optionsData['category_icon'] = $optionInputData['category_icon'];
|
||||
}
|
||||
$optionsData['settings_class'] = $className;
|
||||
|
||||
$settings[str_replace('Settings', '', class_basename($className))] = $optionsData;
|
||||
//Get all tabs as laravel view paths
|
||||
$tabs = [];
|
||||
if(file_exists(Theme::getViewPaths()[0] . '/admin/settings/tabs/')){
|
||||
$tabspath = glob(Theme::getViewPaths()[0] . '/admin/settings/tabs/*.blade.php');
|
||||
}else{
|
||||
$tabspath = glob(Theme::path($path = 'views', $themeName = 'default').'/admin/settings/tabs/*.blade.php');
|
||||
}
|
||||
|
||||
$settings->sort();
|
||||
foreach ($tabspath as $filename) {
|
||||
$tabs[] = 'admin.settings.tabs.'.basename($filename, '.blade.php');
|
||||
}
|
||||
|
||||
|
||||
//Generate a html list item for each tab based on tabs file basename, set first tab as active
|
||||
$tabListItems = [];
|
||||
foreach ($tabs as $tab) {
|
||||
$tabName = str_replace('admin.settings.tabs.', '', $tab);
|
||||
$tabListItems[] = '<li class="nav-item">
|
||||
<a class="nav-link '.(empty($tabListItems) ? 'active' : '').'" data-toggle="pill" href="#'.$tabName.'">
|
||||
'.__(ucfirst($tabName)).'
|
||||
</a></li>';
|
||||
}
|
||||
|
||||
$themes = array_diff(scandir(base_path('themes')), array('..', '.'));
|
||||
|
||||
return view('admin.settings.index', [
|
||||
'settings' => $settings->all(),
|
||||
'tabs' => $tabs,
|
||||
'tabListItems' => $tabListItems,
|
||||
'themes' => $themes,
|
||||
'active_theme' => Theme::active(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
*/
|
||||
public function update(Request $request)
|
||||
{
|
||||
$category = request()->get('category');
|
||||
$settings_class = request()->get('settings_class');
|
||||
|
||||
if (method_exists($settings_class, 'getValidations')) {
|
||||
$validations = $settings_class::getValidations();
|
||||
} else {
|
||||
$validations = [];
|
||||
}
|
||||
|
||||
|
||||
$validator = Validator::make($request->all(), $validations);
|
||||
if ($validator->fails()) {
|
||||
return Redirect::to('admin/settings' . '#' . $category)->withErrors($validator)->withInput();
|
||||
}
|
||||
|
||||
$settingsClass = new $settings_class();
|
||||
|
||||
foreach ($settingsClass->toArray() as $key => $value) {
|
||||
// Get the type of the settingsclass property
|
||||
$rp = new \ReflectionProperty($settingsClass, $key);
|
||||
$rpType = $rp->getType();
|
||||
|
||||
if ($rpType == 'bool') {
|
||||
$settingsClass->$key = $request->has($key);
|
||||
continue;
|
||||
}
|
||||
|
||||
$nullable = $rpType->allowsNull();
|
||||
if ($nullable) $settingsClass->$key = $request->input($key) ?? null;
|
||||
else $settingsClass->$key = $request->input($key);
|
||||
}
|
||||
|
||||
$settingsClass->save();
|
||||
|
||||
|
||||
return Redirect::to('admin/settings' . '#' . $category)->with('success', 'Settings updated successfully.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\ShopProduct;
|
||||
use App\Settings\GeneralSettings;
|
||||
use App\Settings\LocaleSettings;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
@ -22,14 +20,20 @@ class ShopProductController extends Controller
|
|||
*
|
||||
* @return Application|Factory|View|Response
|
||||
*/
|
||||
public function index(LocaleSettings $locale_settings, GeneralSettings $general_settings)
|
||||
public function index(Request $request)
|
||||
{
|
||||
$isStoreEnabled = $general_settings->store_enabled;
|
||||
$isPaymentSetup = false;
|
||||
|
||||
if (
|
||||
env('APP_ENV') == 'local' ||
|
||||
config('SETTINGS::PAYMENTS:PAYPAL:SECRET') && config('SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID') ||
|
||||
config('SETTINGS::PAYMENTS:STRIPE:SECRET') && config('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET') && config('SETTINGS::PAYMENTS:STRIPE:METHODS')
|
||||
) {
|
||||
$isPaymentSetup = true;
|
||||
}
|
||||
|
||||
return view('admin.store.index', [
|
||||
'isStoreEnabled' => $isStoreEnabled,
|
||||
'locale_datatables' => $locale_settings->datatables
|
||||
'isPaymentSetup' => $isPaymentSetup,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -38,11 +42,10 @@ class ShopProductController extends Controller
|
|||
*
|
||||
* @return Application|Factory|View|Response
|
||||
*/
|
||||
public function create(GeneralSettings $general_settings)
|
||||
public function create()
|
||||
{
|
||||
return view('admin.store.create', [
|
||||
'currencyCodes' => config('currency_codes'),
|
||||
'credits_display_name' => $general_settings->credits_display_name
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -76,12 +79,11 @@ class ShopProductController extends Controller
|
|||
* @param ShopProduct $shopProduct
|
||||
* @return Application|Factory|View|Response
|
||||
*/
|
||||
public function edit(ShopProduct $shopProduct, GeneralSettings $general_settings)
|
||||
public function edit(ShopProduct $shopProduct)
|
||||
{
|
||||
return view('admin.store.edit', [
|
||||
'currencyCodes' => config('currency_codes'),
|
||||
'shopProduct' => $shopProduct,
|
||||
'credits_display_name' => $general_settings->credits_display_name
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -115,7 +117,7 @@ class ShopProductController extends Controller
|
|||
* @param ShopProduct $shopProduct
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function disable(ShopProduct $shopProduct)
|
||||
public function disable(Request $request, ShopProduct $shopProduct)
|
||||
{
|
||||
$shopProduct->update(['disabled' => !$shopProduct->disabled]);
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ namespace App\Http\Controllers\Admin;
|
|||
use App\Enums\UsefulLinkLocation;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\UsefulLink;
|
||||
use App\Settings\LocaleSettings;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
@ -20,11 +19,9 @@ class UsefulLinkController extends Controller
|
|||
*
|
||||
* @return Application|Factory|View|Response
|
||||
*/
|
||||
public function index(LocaleSettings $locale_settings)
|
||||
public function index()
|
||||
{
|
||||
return view('admin.usefullinks.index', [
|
||||
'locale_datatables' => $locale_settings->datatables
|
||||
]);
|
||||
return view('admin.usefullinks.index');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,14 +2,11 @@
|
|||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Classes\Pterodactyl;
|
||||
use App\Events\UserUpdateCreditsEvent;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use App\Notifications\DynamicNotification;
|
||||
use App\Settings\LocaleSettings;
|
||||
use App\Settings\PterodactylSettings;
|
||||
use App\Classes\PterodactylClient;
|
||||
use App\Settings\GeneralSettings;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
|
@ -29,11 +26,12 @@ use Spatie\QueryBuilder\QueryBuilder;
|
|||
|
||||
class UserController extends Controller
|
||||
{
|
||||
private $pterodactyl;
|
||||
|
||||
public function __construct(PterodactylSettings $ptero_settings)
|
||||
private Pterodactyl $pterodactyl;
|
||||
|
||||
public function __construct(Pterodactyl $pterodactyl)
|
||||
{
|
||||
$this->pterodactyl = new PterodactylClient($ptero_settings);
|
||||
$this->pterodactyl = $pterodactyl;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,12 +40,9 @@ class UserController extends Controller
|
|||
* @param Request $request
|
||||
* @return Application|Factory|View|Response
|
||||
*/
|
||||
public function index(LocaleSettings $locale_settings, GeneralSettings $general_settings)
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view('admin.users.index', [
|
||||
'locale_datatables' => $locale_settings->datatables,
|
||||
'credits_display_name' => $general_settings->credits_display_name
|
||||
]);
|
||||
return view('admin.users.index');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,7 +51,7 @@ class UserController extends Controller
|
|||
* @param User $user
|
||||
* @return Application|Factory|View|Response
|
||||
*/
|
||||
public function show(User $user, LocaleSettings $locale_settings, GeneralSettings $general_settings)
|
||||
public function show(User $user)
|
||||
{
|
||||
//QUERY ALL REFERRALS A USER HAS
|
||||
//i am not proud of this at all.
|
||||
|
@ -70,8 +65,6 @@ class UserController extends Controller
|
|||
return view('admin.users.show')->with([
|
||||
'user' => $user,
|
||||
'referrals' => $allReferals,
|
||||
'locale_datatables' => $locale_settings->datatables,
|
||||
'credits_display_name' => $general_settings->credits_display_name
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -106,11 +99,10 @@ class UserController extends Controller
|
|||
* @param User $user
|
||||
* @return Application|Factory|View|Response
|
||||
*/
|
||||
public function edit(User $user, GeneralSettings $general_settings)
|
||||
public function edit(User $user)
|
||||
{
|
||||
return view('admin.users.edit')->with([
|
||||
'user' => $user,
|
||||
'credits_display_name' => $general_settings->credits_display_name
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -166,10 +158,6 @@ class UserController extends Controller
|
|||
*/
|
||||
public function destroy(User $user)
|
||||
{
|
||||
if ($user->role === 'admin' && User::query()->where('role', 'admin')->count() === 1) {
|
||||
return redirect()->back()->with('error', __('You can not delete the last admin!'));
|
||||
}
|
||||
|
||||
$user->delete();
|
||||
|
||||
return redirect()->back()->with('success', __('user has been removed!'));
|
||||
|
@ -181,7 +169,7 @@ class UserController extends Controller
|
|||
* @param User $user
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function verifyEmail(User $user)
|
||||
public function verifyEmail(Request $request, User $user)
|
||||
{
|
||||
$user->verifyEmail();
|
||||
|
||||
|
@ -219,7 +207,7 @@ class UserController extends Controller
|
|||
* @param User $user
|
||||
* @return Application|Factory|View|Response
|
||||
*/
|
||||
public function notifications()
|
||||
public function notifications(User $user)
|
||||
{
|
||||
return view('admin.users.notifications');
|
||||
}
|
||||
|
@ -260,11 +248,7 @@ class UserController extends Controller
|
|||
}
|
||||
$all = $data['all'] ?? false;
|
||||
$users = $all ? User::all() : User::whereIn('id', $data['users'])->get();
|
||||
try {
|
||||
Notification::send($users, new DynamicNotification($data['via'], $database, $mail));
|
||||
} catch (Exception $e) {
|
||||
return redirect()->route('admin.users.notifications')->with('error', __('The attempt to send the email failed with the error: ' . $e->getMessage()));
|
||||
}
|
||||
Notification::send($users, new DynamicNotification($data['via'], $database, $mail));
|
||||
|
||||
return redirect()->route('admin.users.notifications')->with('success', __('Notification sent!'));
|
||||
}
|
||||
|
@ -349,8 +333,8 @@ class UserController extends Controller
|
|||
->editColumn('last_seen', function (User $user) {
|
||||
return $user->last_seen ? $user->last_seen->diffForHumans() : __('Never');
|
||||
})
|
||||
->editColumn('name', function (User $user, PterodactylSettings $ptero_settings) {
|
||||
return '<a class="text-info" target="_blank" href="' . $ptero_settings->panel_url . '/admin/users/view/' . $user->pterodactyl_id . '">' . strip_tags($user->name) . '</a>';
|
||||
->editColumn('name', function (User $user) {
|
||||
return '<a class="text-info" target="_blank" href="' . config('SETTINGS::SYSTEM:PTERODACTYL:URL') . '/admin/users/view/' . $user->pterodactyl_id . '">' . strip_tags($user->name) . '</a>';
|
||||
})
|
||||
->rawColumns(['avatar', 'name', 'credits', 'role', 'usage', 'actions'])
|
||||
->make();
|
||||
|
|
|
@ -6,8 +6,6 @@ use App\Events\UserUpdateCreditsEvent;
|
|||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use App\Models\Voucher;
|
||||
use App\Settings\GeneralSettings;
|
||||
use App\Settings\LocaleSettings;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
@ -24,12 +22,9 @@ class VoucherController extends Controller
|
|||
*
|
||||
* @return Application|Factory|View
|
||||
*/
|
||||
public function index(LocaleSettings $locale_settings, GeneralSettings $general_settings)
|
||||
public function index()
|
||||
{
|
||||
return view('admin.vouchers.index', [
|
||||
'locale_datatables' => $locale_settings->datatables,
|
||||
'credits_display_name' => $general_settings->credits_display_name
|
||||
]);
|
||||
return view('admin.vouchers.index');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,11 +32,9 @@ class VoucherController extends Controller
|
|||
*
|
||||
* @return Application|Factory|View
|
||||
*/
|
||||
public function create(GeneralSettings $general_settings)
|
||||
public function create()
|
||||
{
|
||||
return view('admin.vouchers.create', [
|
||||
'credits_display_name' => $general_settings->credits_display_name
|
||||
]);
|
||||
return view('admin.vouchers.create');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,11 +75,10 @@ class VoucherController extends Controller
|
|||
* @param Voucher $voucher
|
||||
* @return Application|Factory|View
|
||||
*/
|
||||
public function edit(Voucher $voucher, GeneralSettings $general_settings)
|
||||
public function edit(Voucher $voucher)
|
||||
{
|
||||
return view('admin.vouchers.edit', [
|
||||
'voucher' => $voucher,
|
||||
'credits_display_name' => $general_settings->credits_display_name
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -125,12 +117,10 @@ class VoucherController extends Controller
|
|||
return redirect()->back()->with('success', __('voucher has been removed!'));
|
||||
}
|
||||
|
||||
public function users(Voucher $voucher, LocaleSettings $locale_settings, GeneralSettings $general_settings)
|
||||
public function users(Voucher $voucher)
|
||||
{
|
||||
return view('admin.vouchers.users', [
|
||||
'voucher' => $voucher,
|
||||
'locale_datatables' => $locale_settings->datatables,
|
||||
'credits_display_name' => $general_settings->credits_display_name
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -140,7 +130,7 @@ class VoucherController extends Controller
|
|||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function redeem(Request $request, GeneralSettings $general_settings)
|
||||
public function redeem(Request $request)
|
||||
{
|
||||
//general validations
|
||||
$request->validate([
|
||||
|
@ -171,7 +161,7 @@ class VoucherController extends Controller
|
|||
|
||||
if ($request->user()->credits + $voucher->credits >= 99999999) {
|
||||
throw ValidationException::withMessages([
|
||||
'code' => "You can't redeem this voucher because you would exceed the limit of " . $general_settings->credits_display_name,
|
||||
'code' => "You can't redeem this voucher because you would exceed the limit of ".CREDITS_DISPLAY_NAME,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -181,7 +171,7 @@ class VoucherController extends Controller
|
|||
event(new UserUpdateCreditsEvent($request->user()));
|
||||
|
||||
return response()->json([
|
||||
'success' => "{$voucher->credits} ". $general_settings->credits_display_name .' '.__('have been added to your balance!'),
|
||||
'success' => "{$voucher->credits} ".CREDITS_DISPLAY_NAME.' '.__('have been added to your balance!'),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ use Illuminate\Support\Facades\Notification;
|
|||
use Illuminate\Support\HtmlString;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Spatie\ValidationRules\Rules\Delimited;
|
||||
use Exception;
|
||||
|
||||
class NotificationController extends Controller
|
||||
{
|
||||
|
@ -105,12 +104,8 @@ class NotificationController extends Controller
|
|||
'users' => ['No users found!'],
|
||||
]);
|
||||
}
|
||||
try {
|
||||
Notification::send($users, new DynamicNotification($via, $database, $mail));
|
||||
}
|
||||
catch (Exception $e) {
|
||||
return response()->json(['message' => 'The attempt to send the email failed with the error: ' . $e->getMessage()], 500);
|
||||
}
|
||||
|
||||
Notification::send($users, new DynamicNotification($via, $database, $mail));
|
||||
|
||||
return response()->json(['message' => 'Notification successfully sent.', 'user_count' => $users->count()]);
|
||||
}
|
||||
|
|
|
@ -2,16 +2,13 @@
|
|||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Classes\Pterodactyl;
|
||||
use App\Events\UserUpdateCreditsEvent;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\DiscordUser;
|
||||
use App\Models\User;
|
||||
use App\Notifications\ReferralNotification;
|
||||
use App\Traits\Referral;
|
||||
use App\Settings\PterodactylSettings;
|
||||
use App\Classes\PterodactylClient;
|
||||
use App\Settings\ReferralSettings;
|
||||
use App\Settings\UserSettings;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||
|
@ -37,13 +34,6 @@ class UserController extends Controller
|
|||
|
||||
const ALLOWED_FILTERS = ['name', 'server_limit', 'email', 'pterodactyl_id', 'role', 'suspended'];
|
||||
|
||||
private $pterodactyl;
|
||||
|
||||
public function __construct(PterodactylSettings $ptero_settings)
|
||||
{
|
||||
$this->pterodactyl = new PterodactylClient($ptero_settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
|
@ -105,7 +95,7 @@ class UserController extends Controller
|
|||
|
||||
//Update Users Password on Pterodactyl
|
||||
//Username,Mail,First and Lastname are required aswell
|
||||
$response = $this->pterodactyl->application->patch('/application/users/' . $user->pterodactyl_id, [
|
||||
$response = Pterodactyl::client()->patch('/application/users/' . $user->pterodactyl_id, [
|
||||
'username' => $request->name,
|
||||
'first_name' => $request->name,
|
||||
'last_name' => $request->name,
|
||||
|
@ -213,7 +203,7 @@ class UserController extends Controller
|
|||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function suspend(int $id)
|
||||
public function suspend(Request $request, int $id)
|
||||
{
|
||||
$discordUser = DiscordUser::find($id);
|
||||
$user = $discordUser ? $discordUser->user : User::findOrFail($id);
|
||||
|
@ -237,7 +227,7 @@ class UserController extends Controller
|
|||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function unsuspend(int $id)
|
||||
public function unsuspend(Request $request, int $id)
|
||||
{
|
||||
$discordUser = DiscordUser::find($id);
|
||||
$user = $discordUser ? $discordUser->user : User::findOrFail($id);
|
||||
|
@ -256,7 +246,7 @@ class UserController extends Controller
|
|||
/**
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function store(Request $request, UserSettings $user_settings, ReferralSettings $referral_settings)
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'name' => ['required', 'string', 'max:30', 'min:4', 'alpha_num', 'unique:users'],
|
||||
|
@ -265,7 +255,7 @@ class UserController extends Controller
|
|||
]);
|
||||
|
||||
// Prevent the creation of new users via API if this is enabled.
|
||||
if (!$user_settings->creation_enabled) {
|
||||
if (!config('SETTINGS::SYSTEM:CREATION_OF_NEW_USERS', 'true')) {
|
||||
throw ValidationException::withMessages([
|
||||
'error' => 'The creation of new users has been blocked by the system administrator.',
|
||||
]);
|
||||
|
@ -274,13 +264,13 @@ class UserController extends Controller
|
|||
$user = User::create([
|
||||
'name' => $request->input('name'),
|
||||
'email' => $request->input('email'),
|
||||
'credits' => $user_settings->initial_credits,
|
||||
'server_limit' => $user_settings->initial_server_limit,
|
||||
'credits' => config('SETTINGS::USER:INITIAL_CREDITS', 150),
|
||||
'server_limit' => config('SETTINGS::USER:INITIAL_SERVER_LIMIT', 1),
|
||||
'password' => Hash::make($request->input('password')),
|
||||
'referral_code' => $this->createReferralCode(),
|
||||
]);
|
||||
|
||||
$response = $this->pterodactyl->application->post('/application/users', [
|
||||
$response = Pterodactyl::client()->post('/application/users', [
|
||||
'external_id' => App::environment('local') ? Str::random(16) : (string) $user->id,
|
||||
'username' => $user->name,
|
||||
'email' => $user->email,
|
||||
|
@ -307,8 +297,8 @@ class UserController extends Controller
|
|||
$ref_code = $request->input('referral_code');
|
||||
$new_user = $user->id;
|
||||
if ($ref_user = User::query()->where('referral_code', '=', $ref_code)->first()) {
|
||||
if ($referral_settings->mode === 'register' || $referral_settings->mode === 'both') {
|
||||
$ref_user->increment('credits', $referral_settings->reward);
|
||||
if (config('SETTINGS::REFERRAL:MODE') == 'register' || config('SETTINGS::REFERRAL:MODE') == 'both') {
|
||||
$ref_user->increment('credits', config('SETTINGS::REFERRAL::REWARD'));
|
||||
$ref_user->notify(new ReferralNotification($ref_user->id, $new_user));
|
||||
}
|
||||
//INSERT INTO USER_REFERRALS TABLE
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Settings\GeneralSettings;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
|
@ -32,13 +31,13 @@ class ForgotPasswordController extends Controller
|
|||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
protected function validateEmail(Request $request, GeneralSettings $general_settings)
|
||||
protected function validateEmail(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'email' => ['required', 'string', 'email', 'max:255'],
|
||||
]);
|
||||
|
||||
if ($general_settings->recaptcha_enabled) {
|
||||
if (config('SETTINGS::RECAPTCHA:ENABLED') == 'true') {
|
||||
$this->validate($request, [
|
||||
'g-recaptcha-response' => 'required|recaptcha',
|
||||
]);
|
||||
|
|
|
@ -4,7 +4,6 @@ namespace App\Http\Controllers\Auth;
|
|||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use App\Settings\GeneralSettings;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
@ -54,13 +53,13 @@ class LoginController extends Controller
|
|||
return $field;
|
||||
}
|
||||
|
||||
public function login(Request $request, GeneralSettings $general_settings)
|
||||
public function login(Request $request)
|
||||
{
|
||||
$validationRules = [
|
||||
$this->username() => 'required|string',
|
||||
'password' => 'required|string',
|
||||
];
|
||||
if ($general_settings->recaptcha_enabled) {
|
||||
if (config('SETTINGS::RECAPTCHA:ENABLED') == 'true') {
|
||||
$validationRules['g-recaptcha-response'] = ['required', 'recaptcha'];
|
||||
}
|
||||
$request->validate($validationRules);
|
||||
|
|
|
@ -2,18 +2,13 @@
|
|||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Classes\Pterodactyl;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use App\Notifications\ReferralNotification;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use App\Traits\Referral;
|
||||
use Carbon\Carbon;
|
||||
use App\Settings\PterodactylSettings;
|
||||
use App\Classes\PterodactylClient;
|
||||
use App\Settings\GeneralSettings;
|
||||
use App\Settings\ReferralSettings;
|
||||
use App\Settings\UserSettings;
|
||||
use App\Settings\WebsiteSettings;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
@ -25,24 +20,6 @@ use Illuminate\Validation\ValidationException;
|
|||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
private $pterodactyl;
|
||||
|
||||
private $credits_display_name;
|
||||
|
||||
private $recaptcha_enabled;
|
||||
|
||||
private $website_show_tos;
|
||||
|
||||
private $register_ip_check;
|
||||
|
||||
private $initial_credits;
|
||||
|
||||
private $initial_server_limit;
|
||||
|
||||
private $referral_mode;
|
||||
|
||||
private $referral_reward;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Register Controller
|
||||
|
@ -68,18 +45,9 @@ class RegisterController extends Controller
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(PterodactylSettings $ptero_settings, GeneralSettings $general_settings, WebsiteSettings $website_settings, UserSettings $user_settings, ReferralSettings $referral_settings)
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest');
|
||||
$this->pterodactyl = new PterodactylClient($ptero_settings);
|
||||
$this->credits_display_name = $general_settings->credits_display_name;
|
||||
$this->recaptcha_enabled = $general_settings->recaptcha_enabled;
|
||||
$this->website_show_tos = $website_settings->show_tos;
|
||||
$this->register_ip_check = $user_settings->register_ip_check;
|
||||
$this->initial_credits = $user_settings->initial_credits;
|
||||
$this->initial_server_limit = $user_settings->initial_server_limit;
|
||||
$this->referral_mode = $referral_settings->mode;
|
||||
$this->referral_reward = $referral_settings->reward;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -95,14 +63,14 @@ class RegisterController extends Controller
|
|||
'email' => ['required', 'string', 'email', 'max:64', 'unique:users'],
|
||||
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
||||
];
|
||||
if ($this->recaptcha_enabled) {
|
||||
if (config('SETTINGS::RECAPTCHA:ENABLED') == 'true') {
|
||||
$validationRules['g-recaptcha-response'] = ['required', 'recaptcha'];
|
||||
}
|
||||
if ($this->website_show_tos) {
|
||||
if (config('SETTINGS::SYSTEM:SHOW_TOS') == 'true') {
|
||||
$validationRules['terms'] = ['required'];
|
||||
}
|
||||
|
||||
if ($this->register_ip_check) {
|
||||
if (config('SETTINGS::SYSTEM:REGISTER_IP_CHECK', 'true') == 'true') {
|
||||
|
||||
//check if ip has already made an account
|
||||
$data['ip'] = session()->get('ip') ?? request()->ip();
|
||||
|
@ -131,16 +99,15 @@ class RegisterController extends Controller
|
|||
$user = User::create([
|
||||
'name' => $data['name'],
|
||||
'email' => $data['email'],
|
||||
'credits' => $this->initial_credits,
|
||||
'server_limit' => $this->initial_server_limit,
|
||||
'credits' => config('SETTINGS::USER:INITIAL_CREDITS', 150),
|
||||
'server_limit' => config('SETTINGS::USER:INITIAL_SERVER_LIMIT', 1),
|
||||
'password' => Hash::make($data['password']),
|
||||
'referral_code' => $this->createReferralCode(),
|
||||
'pterodactyl_id' => Str::uuid(),
|
||||
|
||||
]);
|
||||
|
||||
$response = $this->pterodactyl->application->post('/application/users', [
|
||||
'external_id' => $user->pterodactyl_id,
|
||||
$response = Pterodactyl::client()->post('/application/users', [
|
||||
'external_id' => App::environment('local') ? Str::random(16) : (string) $user->id,
|
||||
'username' => $user->name,
|
||||
'email' => $user->email,
|
||||
'first_name' => $user->name,
|
||||
|
@ -158,23 +125,24 @@ class RegisterController extends Controller
|
|||
]);
|
||||
}
|
||||
|
||||
// delete activity log for user creation where description = 'created' or 'deleted' and subject_id = user_id
|
||||
DB::table('activity_log')->where('description', 'created')->orWhere('description', 'deleted')->where('subject_id', $user->id)->delete();
|
||||
$user->update([
|
||||
'pterodactyl_id' => $response->json()['attributes']['id'],
|
||||
]);
|
||||
|
||||
//INCREMENT REFERRAL-USER CREDITS
|
||||
if (!empty($data['referral_code'])) {
|
||||
$ref_code = $data['referral_code'];
|
||||
$new_user = $user->id;
|
||||
if ($ref_user = User::query()->where('referral_code', '=', $ref_code)->first()) {
|
||||
if ($this->referral_mode === 'sign-up' || $this->referral_mode === 'both') {
|
||||
$ref_user->increment('credits', $this->referral_reward);
|
||||
if (config('SETTINGS::REFERRAL:MODE') == 'sign-up' || config('SETTINGS::REFERRAL:MODE') == 'both') {
|
||||
$ref_user->increment('credits', config('SETTINGS::REFERRAL::REWARD'));
|
||||
$ref_user->notify(new ReferralNotification($ref_user->id, $new_user));
|
||||
|
||||
//LOGS REFERRALS IN THE ACTIVITY LOG
|
||||
activity()
|
||||
->performedOn($user)
|
||||
->causedBy($ref_user)
|
||||
->log('gained ' . $this->referral_reward . ' ' . $this->credits_display_name . ' for sign-up-referral of ' . $user->name . ' (ID:' . $user->id . ')');
|
||||
->log('gained ' . config('SETTINGS::REFERRAL::REWARD') . ' ' . config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME') . ' for sign-up-referral of ' . $user->name . ' (ID:' . $user->id . ')');
|
||||
}
|
||||
//INSERT INTO USER_REFERRALS TABLE
|
||||
DB::table('user_referrals')->insert([
|
||||
|
|
|
@ -5,24 +5,22 @@ namespace App\Http\Controllers\Auth;
|
|||
use App\Http\Controllers\Controller;
|
||||
use App\Models\DiscordUser;
|
||||
use App\Models\User;
|
||||
use App\Settings\DiscordSettings;
|
||||
use App\Settings\UserSettings;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Laravel\Socialite\Facades\Socialite;
|
||||
|
||||
class SocialiteController extends Controller
|
||||
{
|
||||
public function redirect(DiscordSettings $discord_settings)
|
||||
public function redirect()
|
||||
{
|
||||
$scopes = !empty($discord_settings->bot_token) && !empty($discord_settings->guild_id) ? ['guilds.join'] : [];
|
||||
$scopes = ! empty(config('SETTINGS::DISCORD:BOT_TOKEN')) && ! empty(config('SETTINGS::DISCORD:GUILD_ID')) ? ['guilds.join'] : [];
|
||||
|
||||
return Socialite::driver('discord')
|
||||
->scopes($scopes)
|
||||
->redirect();
|
||||
}
|
||||
|
||||
public function callback(DiscordSettings $discord_settings, UserSettings $user_settings)
|
||||
public function callback()
|
||||
{
|
||||
if (Auth::guest()) {
|
||||
return abort(500);
|
||||
|
@ -31,9 +29,9 @@ class SocialiteController extends Controller
|
|||
/** @var User $user */
|
||||
$user = Auth::user();
|
||||
$discord = Socialite::driver('discord')->user();
|
||||
$botToken = $discord_settings->bot_token;
|
||||
$guildId = $discord_settings->guild_id;
|
||||
$roleId = $discord_settings->role_id;
|
||||
$botToken = config('SETTINGS::DISCORD:BOT_TOKEN');
|
||||
$guildId = config('SETTINGS::DISCORD:GUILD_ID');
|
||||
$roleId = config('SETTINGS::DISCORD:ROLE_ID');
|
||||
|
||||
//save / update discord_users
|
||||
|
||||
|
@ -51,8 +49,8 @@ class SocialiteController extends Controller
|
|||
DiscordUser::create(array_merge($discord->user, ['user_id' => Auth::user()->id]));
|
||||
|
||||
//update user
|
||||
Auth::user()->increment('credits', $user_settings->credits_reward_after_verify_discord);
|
||||
Auth::user()->increment('server_limit', $user_settings->server_limit_after_verify_discord);
|
||||
Auth::user()->increment('credits', config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD'));
|
||||
Auth::user()->increment('server_limit', config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD'));
|
||||
Auth::user()->update(['discord_verified_at' => now()]);
|
||||
} else {
|
||||
$user->discordUser->update($discord->user);
|
||||
|
|
|
@ -4,9 +4,7 @@ namespace App\Http\Controllers;
|
|||
|
||||
use App\Models\PartnerDiscount;
|
||||
use App\Models\UsefulLink;
|
||||
use App\Settings\GeneralSettings;
|
||||
use App\Settings\WebsiteSettings;
|
||||
use App\Settings\ReferralSettings;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
@ -91,7 +89,7 @@ class HomeController extends Controller
|
|||
}
|
||||
|
||||
/** Show the application dashboard. */
|
||||
public function index(GeneralSettings $general_settings, WebsiteSettings $website_settings, ReferralSettings $referral_settings)
|
||||
public function index(Request $request)
|
||||
{
|
||||
$usage = Auth::user()->creditUsage();
|
||||
$credits = Auth::user()->Credits();
|
||||
|
@ -122,9 +120,6 @@ class HomeController extends Controller
|
|||
'numberOfReferrals' => DB::table('user_referrals')->where('referral_id', '=', Auth::user()->id)->count(),
|
||||
'partnerDiscount' => PartnerDiscount::where('user_id', Auth::user()->id)->first(),
|
||||
'myDiscount' => PartnerDiscount::getDiscount(),
|
||||
'general_settings' => $general_settings,
|
||||
'website_settings' => $website_settings,
|
||||
'referral_settings' => $referral_settings
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,23 +10,20 @@ use App\Models\TicketCategory;
|
|||
use App\Models\TicketComment;
|
||||
use App\Models\User;
|
||||
use App\Notifications\Ticket\User\ReplyNotification;
|
||||
use App\Settings\LocaleSettings;
|
||||
use App\Settings\PterodactylSettings;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class TicketsController extends Controller
|
||||
{
|
||||
public function index(LocaleSettings $locale_settings)
|
||||
public function index()
|
||||
{
|
||||
return view('moderator.ticket.index', [
|
||||
'tickets' => Ticket::orderBy('id', 'desc')->paginate(10),
|
||||
'ticketcategories' => TicketCategory::all(),
|
||||
'locale_datatables' => $locale_settings->datatables
|
||||
]);
|
||||
$tickets = Ticket::orderBy('id', 'desc')->paginate(10);
|
||||
$ticketcategories = TicketCategory::all();
|
||||
|
||||
return view('moderator.ticket.index', compact('tickets', 'ticketcategories'));
|
||||
}
|
||||
|
||||
public function show($ticket_id, PterodactylSettings $ptero_settings)
|
||||
public function show($ticket_id)
|
||||
{
|
||||
try {
|
||||
$ticket = Ticket::where('ticket_id', $ticket_id)->firstOrFail();
|
||||
|
@ -37,9 +34,8 @@ class TicketsController extends Controller
|
|||
$ticketcomments = $ticket->ticketcomments;
|
||||
$ticketcategory = $ticket->ticketcategory;
|
||||
$server = Server::where('id', $ticket->server)->first();
|
||||
$pterodactyl_url = $ptero_settings->panel_url;
|
||||
|
||||
return view('moderator.ticket.show', compact('ticket', 'ticketcategory', 'ticketcomments', 'server', 'pterodactyl_url'));
|
||||
return view('moderator.ticket.show', compact('ticket', 'ticketcategory', 'ticketcomments', 'server'));
|
||||
}
|
||||
|
||||
public function changeStatus($ticket_id)
|
||||
|
@ -168,11 +164,9 @@ class TicketsController extends Controller
|
|||
->make(true);
|
||||
}
|
||||
|
||||
public function blacklist(LocaleSettings $locale_settings)
|
||||
public function blacklist()
|
||||
{
|
||||
return view('moderator.ticket.blacklist', [
|
||||
'locale_datatables' => $locale_settings->datatables
|
||||
]);
|
||||
return view('moderator.ticket.blacklist');
|
||||
}
|
||||
|
||||
public function blacklistAdd(Request $request)
|
||||
|
|
|
@ -2,26 +2,18 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Classes\PterodactylClient;
|
||||
use App\Models\Pterodactyl\Egg;
|
||||
use App\Models\Pterodactyl\Location;
|
||||
use App\Models\Pterodactyl\Node;
|
||||
use App\Classes\Pterodactyl;
|
||||
use App\Models\Egg;
|
||||
use App\Models\Location;
|
||||
use App\Models\Node;
|
||||
use App\Models\Product;
|
||||
use App\Settings\PterodactylSettings;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class ProductController extends Controller
|
||||
{
|
||||
private $pterodactyl;
|
||||
|
||||
public function __construct(PterodactylSettings $ptero_settings)
|
||||
{
|
||||
$this->pterodactyl = new PterodactylClient($ptero_settings);
|
||||
}
|
||||
|
||||
{
|
||||
/**
|
||||
* @description get product locations based on selected egg
|
||||
*
|
||||
|
@ -68,7 +60,7 @@ class ProductController extends Controller
|
|||
{
|
||||
$nodes = $this->getNodesBasedOnEgg($request, $egg);
|
||||
foreach ($nodes as $key => $node) {
|
||||
$pteroNode = $this->pterodactyl->getNode($node->id);
|
||||
$pteroNode = Pterodactyl::getNode($node->id);
|
||||
if ($pteroNode['allocated_resources']['memory'] >= ($pteroNode['memory'] * ($pteroNode['memory_overallocate'] + 100) / 100) || $pteroNode['allocated_resources']['disk'] >= ($pteroNode['disk'] * ($pteroNode['disk_overallocate'] + 100) / 100)) {
|
||||
$nodes->forget($key);
|
||||
}
|
||||
|
@ -117,7 +109,7 @@ class ProductController extends Controller
|
|||
})
|
||||
->get();
|
||||
|
||||
$pteroNode = $this->pterodactyl->getNode($node->id);
|
||||
$pteroNode = Pterodactyl::getNode($node->id);
|
||||
foreach ($products as $key => $product) {
|
||||
if ($product->memory > ($pteroNode['memory'] * ($pteroNode['memory_overallocate'] + 100) / 100) - $pteroNode['allocated_resources']['memory'] || $product->disk > ($pteroNode['disk'] * ($pteroNode['disk_overallocate'] + 100) / 100) - $pteroNode['allocated_resources']['disk']) {
|
||||
$product->doesNotFit = true;
|
||||
|
|
|
@ -2,12 +2,8 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Classes\Pterodactyl;
|
||||
use App\Models\User;
|
||||
use App\Settings\UserSettings;
|
||||
use App\Settings\PterodactylSettings;
|
||||
use App\Classes\PterodactylClient;
|
||||
use App\Settings\DiscordSettings;
|
||||
use App\Settings\ReferralSettings;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
@ -16,15 +12,8 @@ use Illuminate\Validation\ValidationException;
|
|||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
private $pterodactyl;
|
||||
|
||||
public function __construct(PterodactylSettings $ptero_settings)
|
||||
{
|
||||
$this->pterodactyl = new PterodactylClient($ptero_settings);
|
||||
}
|
||||
|
||||
/** Display a listing of the resource. */
|
||||
public function index(UserSettings $user_settings, DiscordSettings $discord_settings, ReferralSettings $referral_settings)
|
||||
public function index()
|
||||
{
|
||||
switch (Auth::user()->role) {
|
||||
case 'admin':
|
||||
|
@ -43,14 +32,10 @@ class ProfileController extends Controller
|
|||
|
||||
return view('profile.index')->with([
|
||||
'user' => Auth::user(),
|
||||
'credits_reward_after_verify_discord' => $user_settings->credits_reward_after_verify_discord,
|
||||
'force_email_verification' => $user_settings->force_email_verification,
|
||||
'force_discord_verification' => $user_settings->force_discord_verification,
|
||||
'credits_reward_after_verify_discord' => config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD'),
|
||||
'force_email_verification' => config('SETTINGS::USER:FORCE_EMAIL_VERIFICATION'),
|
||||
'force_discord_verification' => config('SETTINGS::USER:FORCE_DISCORD_VERIFICATION'),
|
||||
'badgeColor' => $badgeColor,
|
||||
'discord_client_id' => $discord_settings->client_id,
|
||||
'discord_client_secret' => $discord_settings->client_secret,
|
||||
'referral_enabled' => $referral_settings->enabled,
|
||||
'referral_allowed' => $referral_settings->allowed
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -78,15 +63,15 @@ class ProfileController extends Controller
|
|||
$user = User::findOrFail($id);
|
||||
|
||||
//update password if necessary
|
||||
if (!is_null($request->input('new_password'))) {
|
||||
if (! is_null($request->input('new_password'))) {
|
||||
|
||||
//validate password request
|
||||
$request->validate([
|
||||
'current_password' => [
|
||||
'required',
|
||||
function ($attribute, $value, $fail) use ($user) {
|
||||
if (!Hash::check($value, $user->password)) {
|
||||
$fail('The ' . $attribute . ' is invalid.');
|
||||
if (! Hash::check($value, $user->password)) {
|
||||
$fail('The '.$attribute.' is invalid.');
|
||||
}
|
||||
},
|
||||
],
|
||||
|
@ -96,7 +81,7 @@ class ProfileController extends Controller
|
|||
|
||||
//Update Users Password on Pterodactyl
|
||||
//Username,Mail,First and Lastname are required aswell
|
||||
$response = $this->pterodactyl->application->patch('/application/users/' . $user->pterodactyl_id, [
|
||||
$response = Pterodactyl::client()->patch('/application/users/'.$user->pterodactyl_id, [
|
||||
'password' => $request->input('new_password'),
|
||||
'username' => $request->input('name'),
|
||||
'first_name' => $request->input('name'),
|
||||
|
@ -118,13 +103,13 @@ class ProfileController extends Controller
|
|||
|
||||
//validate request
|
||||
$request->validate([
|
||||
'name' => 'required|min:4|max:30|alpha_num|unique:users,name,' . $id . ',id',
|
||||
'email' => 'required|email|max:64|unique:users,email,' . $id . ',id',
|
||||
'name' => 'required|min:4|max:30|alpha_num|unique:users,name,'.$id.',id',
|
||||
'email' => 'required|email|max:64|unique:users,email,'.$id.',id',
|
||||
'avatar' => 'nullable',
|
||||
]);
|
||||
|
||||
//update avatar
|
||||
if (!is_null($request->input('avatar'))) {
|
||||
if (! is_null($request->input('avatar'))) {
|
||||
$avatar = json_decode($request->input('avatar'));
|
||||
if ($avatar->input->size > 3000000) {
|
||||
abort(500);
|
||||
|
@ -140,7 +125,7 @@ class ProfileController extends Controller
|
|||
}
|
||||
|
||||
//update name and email on Pterodactyl
|
||||
$response = $this->pterodactyl->application->patch('/application/users/' . $user->pterodactyl_id, [
|
||||
$response = Pterodactyl::client()->patch('/application/users/'.$user->pterodactyl_id, [
|
||||
'username' => $request->input('name'),
|
||||
'first_name' => $request->input('name'),
|
||||
'last_name' => $request->input('name'),
|
||||
|
|
|
@ -2,18 +2,14 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Pterodactyl\Egg;
|
||||
use App\Models\Pterodactyl\Location;
|
||||
use App\Models\Pterodactyl\Nest;
|
||||
use App\Models\Pterodactyl\Node;
|
||||
use App\Classes\Pterodactyl;
|
||||
use App\Models\Egg;
|
||||
use App\Models\Location;
|
||||
use App\Models\Nest;
|
||||
use App\Models\Node;
|
||||
use App\Models\Product;
|
||||
use App\Models\Server;
|
||||
use App\Notifications\ServerCreationError;
|
||||
use App\Settings\UserSettings;
|
||||
use App\Settings\ServerSettings;
|
||||
use App\Settings\PterodactylSettings;
|
||||
use App\Classes\PterodactylClient;
|
||||
use App\Settings\GeneralSettings;
|
||||
use Exception;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Client\Response;
|
||||
|
@ -24,15 +20,8 @@ use Illuminate\Support\Facades\Request as FacadesRequest;
|
|||
|
||||
class ServerController extends Controller
|
||||
{
|
||||
private $pterodactyl;
|
||||
|
||||
public function __construct(PterodactylSettings $ptero_settings)
|
||||
{
|
||||
$this->pterodactyl = new PterodactylClient($ptero_settings);
|
||||
}
|
||||
|
||||
/** Display a listing of the resource. */
|
||||
public function index(GeneralSettings $general_settings, PterodactylSettings $ptero_settings)
|
||||
public function index()
|
||||
{
|
||||
$servers = Auth::user()->servers;
|
||||
|
||||
|
@ -40,7 +29,7 @@ class ServerController extends Controller
|
|||
foreach ($servers as $server) {
|
||||
|
||||
//Get server infos from ptero
|
||||
$serverAttributes = $this->pterodactyl->getServerAttributes($server->pterodactyl_id);
|
||||
$serverAttributes = Pterodactyl::getServerAttributes($server->pterodactyl_id, true);
|
||||
if (! $serverAttributes) {
|
||||
continue;
|
||||
}
|
||||
|
@ -72,19 +61,14 @@ class ServerController extends Controller
|
|||
|
||||
return view('servers.index')->with([
|
||||
'servers' => $servers,
|
||||
'credits_display_name' => $general_settings->credits_display_name,
|
||||
'pterodactyl_url' => $ptero_settings->panel_url,
|
||||
'phpmyadmin_url' => $general_settings->phpmyadmin_url
|
||||
]);
|
||||
}
|
||||
|
||||
/** Show the form for creating a new resource. */
|
||||
public function create(UserSettings $user_settings, ServerSettings $server_settings, GeneralSettings $general_settings)
|
||||
public function create()
|
||||
{
|
||||
$validate_configuration = $this->validateConfigurationRules($user_settings, $server_settings);
|
||||
|
||||
if (!is_null($validate_configuration)) {
|
||||
return $validate_configuration;
|
||||
if (! is_null($this->validateConfigurationRules())) {
|
||||
return $this->validateConfigurationRules();
|
||||
}
|
||||
|
||||
$productCount = Product::query()->where('disabled', '=', false)->count();
|
||||
|
@ -114,16 +98,13 @@ class ServerController extends Controller
|
|||
'locations' => $locations,
|
||||
'eggs' => $eggs,
|
||||
'user' => Auth::user(),
|
||||
'server_creation_enabled' => $server_settings->creation_enabled,
|
||||
'min_credits_to_make_server' => $user_settings->min_credits_to_make_server,
|
||||
'credits_display_name' => $general_settings->credits_display_name
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|RedirectResponse
|
||||
*/
|
||||
private function validateConfigurationRules(UserSettings $user_settings, ServerSettings $server_settings)
|
||||
private function validateConfigurationRules()
|
||||
{
|
||||
//limit validation
|
||||
if (Auth::user()->servers()->count() >= Auth::user()->server_limit) {
|
||||
|
@ -139,31 +120,35 @@ class ServerController extends Controller
|
|||
$nodeName = $node->name;
|
||||
|
||||
// Check if node has enough memory and disk space
|
||||
$checkResponse = $this->pterodactyl->checkNodeResources($node, $product->memory, $product->disk);
|
||||
$checkResponse = Pterodactyl::checkNodeResources($node, $product->memory, $product->disk);
|
||||
if ($checkResponse == false) {
|
||||
return redirect()->route('servers.index')->with('error', __("The node '".$nodeName."' doesn't have the required memory or disk left to allocate this product."));
|
||||
}
|
||||
|
||||
// Min. Credits
|
||||
if (Auth::user()->credits < ($product->minimum_credits == -1
|
||||
? $user_settings->min_credits_to_make_server
|
||||
: $product->minimum_credits)) {
|
||||
if (
|
||||
Auth::user()->credits <
|
||||
($product->minimum_credits == -1
|
||||
? config('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50)
|
||||
: $product->minimum_credits)
|
||||
) {
|
||||
return redirect()->route('servers.index')->with('error', 'You do not have the required amount of '.CREDITS_DISPLAY_NAME.' to use this product!');
|
||||
}
|
||||
}
|
||||
|
||||
//Required Verification for creating an server
|
||||
if ($user_settings->force_email_verification && !Auth::user()->hasVerifiedEmail()) {
|
||||
if (config('SETTINGS::USER:FORCE_EMAIL_VERIFICATION', 'false') === 'true' && ! Auth::user()->hasVerifiedEmail()) {
|
||||
return redirect()->route('profile.index')->with('error', __('You are required to verify your email address before you can create a server.'));
|
||||
}
|
||||
|
||||
//Required Verification for creating an server
|
||||
if (!$server_settings->creation_enabled && Auth::user()->role != 'admin') {
|
||||
|
||||
if (! config('SETTINGS::SYSTEM:CREATION_OF_NEW_SERVERS', 'true') && Auth::user()->role != 'admin') {
|
||||
return redirect()->route('servers.index')->with('error', __('The system administrator has blocked the creation of new servers.'));
|
||||
}
|
||||
|
||||
//Required Verification for creating an server
|
||||
if ($user_settings->force_discord_verification && !Auth::user()->discordUser) {
|
||||
if (config('SETTINGS::USER:FORCE_DISCORD_VERIFICATION', 'false') === 'true' && ! Auth::user()->discordUser) {
|
||||
return redirect()->route('profile.index')->with('error', __('You are required to link your discord account before you can create a server.'));
|
||||
}
|
||||
|
||||
|
@ -171,15 +156,13 @@ class ServerController extends Controller
|
|||
}
|
||||
|
||||
/** Store a newly created resource in storage. */
|
||||
public function store(Request $request, UserSettings $user_settings, ServerSettings $server_settings)
|
||||
public function store(Request $request)
|
||||
{
|
||||
/** @var Node $node */
|
||||
/** @var Egg $egg */
|
||||
/** @var Product $product */
|
||||
$validate_configuration = $this->validateConfigurationRules($user_settings, $server_settings);
|
||||
|
||||
if (!is_null($validate_configuration)) {
|
||||
return $validate_configuration;
|
||||
if (! is_null($this->validateConfigurationRules())) {
|
||||
return $this->validateConfigurationRules();
|
||||
}
|
||||
|
||||
$request->validate([
|
||||
|
@ -200,13 +183,13 @@ class ServerController extends Controller
|
|||
]);
|
||||
|
||||
//get free allocation ID
|
||||
$allocationId = $this->pterodactyl->getFreeAllocationId($node);
|
||||
$allocationId = Pterodactyl::getFreeAllocationId($node);
|
||||
if (! $allocationId) {
|
||||
return $this->noAllocationsError($server);
|
||||
}
|
||||
|
||||
//create server on pterodactyl
|
||||
$response = $this->pterodactyl->createServer($server, $egg, $allocationId);
|
||||
$response = Pterodactyl::createServer($server, $egg, $allocationId);
|
||||
if ($response->failed()) {
|
||||
return $this->serverCreationFailed($response, $server);
|
||||
}
|
||||
|
@ -218,7 +201,7 @@ class ServerController extends Controller
|
|||
'identifier' => $serverAttributes['identifier'],
|
||||
]);
|
||||
|
||||
if ($server_settings->charge_first_hour) {
|
||||
if (config('SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR', 'true') == 'true') {
|
||||
if ($request->user()->credits >= $server->product->getHourlyPrice()) {
|
||||
$request->user()->decrement('credits', $server->product->getHourlyPrice());
|
||||
}
|
||||
|
@ -269,12 +252,12 @@ class ServerController extends Controller
|
|||
}
|
||||
|
||||
/** Show Server Settings */
|
||||
public function show(Server $server, ServerSettings $server_settings, GeneralSettings $general_settings)
|
||||
public function show(Server $server)
|
||||
{
|
||||
if ($server->user_id != Auth::user()->id) {
|
||||
return back()->with('error', __('This is not your Server!'));
|
||||
return back()->with('error', __('´This is not your Server!'));
|
||||
}
|
||||
$serverAttributes = $this->pterodactyl->getServerAttributes($server->pterodactyl_id);
|
||||
$serverAttributes = Pterodactyl::getServerAttributes($server->pterodactyl_id);
|
||||
$serverRelationships = $serverAttributes['relationships'];
|
||||
$serverLocationAttributes = $serverRelationships['location']['attributes'];
|
||||
|
||||
|
@ -290,7 +273,7 @@ class ServerController extends Controller
|
|||
$server->name = $serverAttributes['name'];
|
||||
$server->egg = $serverRelationships['egg']['attributes']['name'];
|
||||
|
||||
$pteroNode = $this->pterodactyl->getNode($serverRelationships['node']['attributes']['id']);
|
||||
$pteroNode = Pterodactyl::getNode($serverRelationships['node']['attributes']['id']);
|
||||
|
||||
$products = Product::orderBy('created_at')
|
||||
->whereHas('nodes', function (Builder $builder) use ($serverRelationships) { //Only show products for that node
|
||||
|
@ -309,8 +292,6 @@ class ServerController extends Controller
|
|||
return view('servers.settings')->with([
|
||||
'server' => $server,
|
||||
'products' => $products,
|
||||
'server_enable_upgrade' => $server_settings->enable_upgrade,
|
||||
'credits_display_name' => $general_settings->credits_display_name
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -325,7 +306,7 @@ class ServerController extends Controller
|
|||
$user = Auth::user();
|
||||
$oldProduct = Product::where('id', $server->product->id)->first();
|
||||
$newProduct = Product::where('id', $request->product_upgrade)->first();
|
||||
$serverAttributes = $this->pterodactyl->getServerAttributes($server->pterodactyl_id);
|
||||
$serverAttributes = Pterodactyl::getServerAttributes($server->pterodactyl_id);
|
||||
$serverRelationships = $serverAttributes['relationships'];
|
||||
|
||||
// Get node resource allocation info
|
||||
|
@ -336,7 +317,7 @@ class ServerController extends Controller
|
|||
// Check if node has enough memory and disk space
|
||||
$requireMemory = $newProduct->memory - $oldProduct->memory;
|
||||
$requiredisk = $newProduct->disk - $oldProduct->disk;
|
||||
$checkResponse = $this->pterodactyl->checkNodeResources($node, $requireMemory, $requiredisk);
|
||||
$checkResponse = Pterodactyl::checkNodeResources($node, $requireMemory, $requiredisk);
|
||||
if ($checkResponse == false) {
|
||||
return redirect()->route('servers.index')->with('error', __("The node '".$nodeName."' doesn't have the required memory or disk left to upgrade the server."));
|
||||
}
|
||||
|
@ -350,12 +331,14 @@ class ServerController extends Controller
|
|||
$server->product_id = $request->product_upgrade;
|
||||
$server->update();
|
||||
$server->allocation = $serverAttributes['allocation'];
|
||||
$response = $this->pterodactyl->updateServer($server, $newProduct);
|
||||
if ($response->failed()) return redirect()->route('servers.index')->with('error', __("The system was unable to update your server product. Please try again later or contact support."));
|
||||
$response = Pterodactyl::updateServer($server, $newProduct);
|
||||
if ($response->failed()) {
|
||||
return $this->serverCreationFailed($response, $server);
|
||||
}
|
||||
//update user balance
|
||||
$user->decrement('credits', $priceupgrade);
|
||||
//restart the server
|
||||
$response = $this->pterodactyl->powerAction($server, 'restart');
|
||||
$response = Pterodactyl::powerAction($server, 'restart');
|
||||
if ($response->failed()) {
|
||||
return redirect()->route('servers.index')->with('error', $response->json()['errors'][0]['detail']);
|
||||
}
|
||||
|
|
|
@ -3,31 +3,36 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\ShopProduct;
|
||||
use App\Settings\GeneralSettings;
|
||||
use App\Settings\UserSettings;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class StoreController extends Controller
|
||||
{
|
||||
/** Display a listing of the resource. */
|
||||
public function index(UserSettings $user_settings, GeneralSettings $general_settings)
|
||||
public function index()
|
||||
{
|
||||
$isStoreEnabled = $general_settings->store_enabled;
|
||||
$isPaymentSetup = false;
|
||||
|
||||
if (
|
||||
env('APP_ENV') == 'local' ||
|
||||
config('SETTINGS::PAYMENTS:PAYPAL:SECRET') && config('SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID') ||
|
||||
config('SETTINGS::PAYMENTS:STRIPE:SECRET') && config('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET') && config('SETTINGS::PAYMENTS:STRIPE:METHODS')
|
||||
) {
|
||||
$isPaymentSetup = true;
|
||||
}
|
||||
|
||||
//Required Verification for creating an server
|
||||
if ($user_settings->force_email_verification && !Auth::user()->hasVerifiedEmail()) {
|
||||
if (config('SETTINGS::USER:FORCE_EMAIL_VERIFICATION', false) === 'true' && ! Auth::user()->hasVerifiedEmail()) {
|
||||
return redirect()->route('profile.index')->with('error', __('You are required to verify your email address before you can purchase credits.'));
|
||||
}
|
||||
|
||||
//Required Verification for creating an server
|
||||
if ($user_settings->force_discord_verification && !Auth::user()->discordUser) {
|
||||
if (config('SETTINGS::USER:FORCE_DISCORD_VERIFICATION', false) === 'true' && ! Auth::user()->discordUser) {
|
||||
return redirect()->route('profile.index')->with('error', __('You are required to link your discord account before you can purchase Credits'));
|
||||
}
|
||||
|
||||
return view('store.index')->with([
|
||||
'products' => ShopProduct::where('disabled', '=', false)->orderBy('type', 'asc')->orderBy('price', 'asc')->get(),
|
||||
'isStoreEnabled' => $isStoreEnabled,
|
||||
'credits_display_name' => $general_settings->credits_display_name
|
||||
'isPaymentSetup' => $isPaymentSetup,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,9 +11,6 @@ use App\Models\User;
|
|||
use App\Notifications\Ticket\Admin\AdminCreateNotification;
|
||||
use App\Notifications\Ticket\Admin\AdminReplyNotification;
|
||||
use App\Notifications\Ticket\User\CreateNotification;
|
||||
use App\Settings\LocaleSettings;
|
||||
use App\Settings\PterodactylSettings;
|
||||
use App\Settings\TicketSettings;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
|
@ -21,28 +18,23 @@ use Illuminate\Support\Str;
|
|||
|
||||
class TicketsController extends Controller
|
||||
{
|
||||
public function index(LocaleSettings $locale_settings)
|
||||
public function index()
|
||||
{
|
||||
return view('ticket.index', [
|
||||
'tickets' => Ticket::where('user_id', Auth::user()->id)->paginate(10),
|
||||
'ticketcategories' => TicketCategory::all(),
|
||||
'locale_datatables' => $locale_settings->datatables
|
||||
]);
|
||||
$tickets = Ticket::where('user_id', Auth::user()->id)->paginate(10);
|
||||
$ticketcategories = TicketCategory::all();
|
||||
|
||||
return view('ticket.index', compact('tickets', 'ticketcategories'));
|
||||
}
|
||||
|
||||
public function store(Request $request, TicketSettings $ticket_settings)
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->validate(
|
||||
$request,
|
||||
[
|
||||
$this->validate($request, [
|
||||
'title' => 'required',
|
||||
'ticketcategory' => 'required',
|
||||
'priority' => 'required',
|
||||
'message' => 'required',
|
||||
]
|
||||
'message' => 'required',]
|
||||
);
|
||||
$ticket = new Ticket(
|
||||
[
|
||||
$ticket = new Ticket([
|
||||
'title' => $request->input('title'),
|
||||
'user_id' => Auth::user()->id,
|
||||
'ticket_id' => strtoupper(Str::random(8)),
|
||||
|
@ -50,28 +42,28 @@ class TicketsController extends Controller
|
|||
'priority' => $request->input('priority'),
|
||||
'message' => $request->input('message'),
|
||||
'status' => 'Open',
|
||||
'server' => $request->input('server'),
|
||||
]
|
||||
'server' => $request->input('server'),]
|
||||
);
|
||||
$ticket->save();
|
||||
$user = Auth::user();
|
||||
switch ($ticket_settings->notify) {
|
||||
case 'all':
|
||||
$admin = User::where('role', 'admin')->orWhere('role', 'mod')->get();
|
||||
Notification::send($admin, new AdminCreateNotification($ticket, $user));
|
||||
case 'admin':
|
||||
$admin = User::where('role', 'admin')->get();
|
||||
Notification::send($admin, new AdminCreateNotification($ticket, $user));
|
||||
case 'moderator':
|
||||
$admin = User::where('role', 'mod')->get();
|
||||
Notification::send($admin, new AdminCreateNotification($ticket, $user));
|
||||
if (config('SETTINGS::TICKET:NOTIFY') == "all") {
|
||||
$admin = User::where('role', 'admin')->orWhere('role', 'mod')->get();
|
||||
}
|
||||
if (config('SETTINGS::TICKET:NOTIFY') == "admin") {
|
||||
$admin = User::where('role', 'admin')->get();
|
||||
}
|
||||
if (config('SETTINGS::TICKET:NOTIFY') == "moderator") {
|
||||
$admin = User::where('role', 'mod')->get();
|
||||
}
|
||||
$user->notify(new CreateNotification($ticket));
|
||||
if (config('SETTINGS::TICKET:NOTIFY') != "none") {
|
||||
Notification::send($admin, new AdminCreateNotification($ticket, $user));
|
||||
}
|
||||
|
||||
return redirect()->route('ticket.index')->with('success', __('A ticket has been opened, ID: #') . $ticket->ticket_id);
|
||||
}
|
||||
|
||||
public function show($ticket_id, PterodactylSettings $ptero_settings)
|
||||
public function show($ticket_id)
|
||||
{
|
||||
try {
|
||||
$ticket = Ticket::where('ticket_id', $ticket_id)->firstOrFail();
|
||||
|
@ -81,9 +73,8 @@ class TicketsController extends Controller
|
|||
$ticketcomments = $ticket->ticketcomments;
|
||||
$ticketcategory = $ticket->ticketcategory;
|
||||
$server = Server::where('id', $ticket->server)->first();
|
||||
$pterodactyl_url = $ptero_settings->panel_url;
|
||||
|
||||
return view('ticket.show', compact('ticket', 'ticketcategory', 'ticketcomments', 'server', 'pterodactyl_url'));
|
||||
return view('ticket.show', compact('ticket', 'ticketcategory', 'ticketcomments', 'server'));
|
||||
}
|
||||
|
||||
public function reply(Request $request)
|
||||
|
@ -179,10 +170,8 @@ class TicketsController extends Controller
|
|||
return __($tickets->priority);
|
||||
})
|
||||
->editColumn('updated_at', function (Ticket $tickets) {
|
||||
return [
|
||||
'display' => $tickets->updated_at ? $tickets->updated_at->diffForHumans() : '',
|
||||
'raw' => $tickets->updated_at ? strtotime($tickets->updated_at) : ''
|
||||
];
|
||||
return ['display' => $tickets->updated_at ? $tickets->updated_at->diffForHumans() : '',
|
||||
'raw' => $tickets->updated_at ? strtotime($tickets->updated_at) : ''];
|
||||
})
|
||||
->addColumn('actions', function (Ticket $tickets) {
|
||||
$statusButtonColor = ($tickets->status == "Closed") ? 'btn-success' : 'btn-warning';
|
||||
|
|
|
@ -16,6 +16,8 @@ class GlobalNames
|
|||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
define('CREDITS_DISPLAY_NAME', config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME', 'Credits'));
|
||||
|
||||
$unsupported_lang_array = explode(',', config('app.unsupported_locales'));
|
||||
$unsupported_lang_array = array_map('strtolower', $unsupported_lang_array);
|
||||
define('UNSUPPORTED_LANGS', $unsupported_lang_array);
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Settings\LocaleSettings;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\App;
|
||||
|
@ -10,12 +9,6 @@ use Illuminate\Support\Facades\Session;
|
|||
|
||||
class SetLocale
|
||||
{
|
||||
private $locale_settings;
|
||||
|
||||
public function __construct(LocaleSettings $locale_settings)
|
||||
{
|
||||
$this->locale_settings = $locale_settings;
|
||||
}
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
|
@ -26,15 +19,15 @@ class SetLocale
|
|||
public function handle($request, Closure $next)
|
||||
{
|
||||
if (Session::has('locale')) {
|
||||
$locale = Session::get('locale', $this->locale_settings->default);
|
||||
$locale = Session::get('locale', config('SETTINGS::LOCALE:DEFAULT'));
|
||||
} else {
|
||||
if (!$this->locale_settings->dynamic) {
|
||||
$locale = $this->locale_settings->default;
|
||||
if (config('SETTINGS::LOCALE:DYNAMIC') !== 'true') {
|
||||
$locale = config('SETTINGS::LOCALE:DEFAULT');
|
||||
} else {
|
||||
$locale = substr($request->server('HTTP_ACCEPT_LANGUAGE'), 0, 2);
|
||||
|
||||
if (! in_array($locale, explode(',', $this->locale_settings->available))) {
|
||||
$locale = $this->locale_settings->default;
|
||||
if (! in_array($locale, explode(',', config('SETTINGS::LOCALE:AVAILABLE')))) {
|
||||
$locale = config('SETTINGS::LOCALE:DEFAULT');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,27 +3,13 @@
|
|||
namespace App\Listeners;
|
||||
|
||||
use App\Events\PaymentEvent;
|
||||
use App\Settings\InvoiceSettings;
|
||||
use App\Traits\Invoiceable;
|
||||
|
||||
class CreateInvoice
|
||||
{
|
||||
|
||||
use Invoiceable;
|
||||
|
||||
private $invoice_enabled;
|
||||
private $invoice_settings;
|
||||
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(InvoiceSettings $invoice_settings)
|
||||
{
|
||||
$this->invoice_enabled = $invoice_settings->enabled;
|
||||
$this->invoice_settings = $invoice_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
|
@ -32,9 +18,9 @@ class CreateInvoice
|
|||
*/
|
||||
public function handle(PaymentEvent $event)
|
||||
{
|
||||
if ($this->invoice_enabled) {
|
||||
if (config('SETTINGS::INVOICE:ENABLED') == 'true') {
|
||||
// create invoice using the trait
|
||||
$this->createInvoice($event->payment, $event->shopProduct, $this->invoice_settings);
|
||||
$this->createInvoice($event->payment, $event->shopProduct);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,24 +4,11 @@ namespace App\Listeners;
|
|||
|
||||
use App\Events\UserUpdateCreditsEvent;
|
||||
use App\Models\Server;
|
||||
use App\Settings\UserSettings;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
|
||||
class UnsuspendServers implements ShouldQueue
|
||||
{
|
||||
private $min_credits_to_make_server;
|
||||
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(UserSettings $user_settings)
|
||||
{
|
||||
$this->min_credits_to_make_server = $user_settings->min_credits_to_make_server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
|
@ -32,7 +19,7 @@ class UnsuspendServers implements ShouldQueue
|
|||
*/
|
||||
public function handle(UserUpdateCreditsEvent $event)
|
||||
{
|
||||
if ($event->user->credits > $this->min_credits_to_make_server) {
|
||||
if ($event->user->credits > config('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50)) {
|
||||
/** @var Server $server */
|
||||
foreach ($event->user->servers as $server) {
|
||||
if ($server->isSuspended()) {
|
||||
|
|
|
@ -6,36 +6,11 @@ use App\Events\PaymentEvent;
|
|||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Models\PartnerDiscount;
|
||||
use App\Settings\GeneralSettings;
|
||||
use App\Settings\ReferralSettings;
|
||||
use App\Settings\UserSettings;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
|
||||
class UserPayment
|
||||
{
|
||||
private $server_limit_after_irl_purchase;
|
||||
|
||||
private $referral_mode;
|
||||
|
||||
private $referral_percentage;
|
||||
|
||||
private $referral_always_give_commission;
|
||||
|
||||
private $credits_display_name;
|
||||
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(UserSettings $user_settings, ReferralSettings $referral_settings, GeneralSettings $general_settings)
|
||||
{
|
||||
$this->server_limit_after_irl_purchase = $user_settings->server_limit_after_irl_purchase;
|
||||
$this->referral_mode = $referral_settings->mode;
|
||||
$this->referral_percentage = $referral_settings->percentage;
|
||||
$this->referral_always_give_commission = $referral_settings->always_give_commission;
|
||||
$this->credits_display_name = $general_settings->credits_display_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
|
@ -53,8 +28,8 @@ class UserPayment
|
|||
}
|
||||
|
||||
//update server limit
|
||||
if ($this->server_limit_after_irl_purchase !== 0 && $user->server_limit < $this->server_limit_after_irl_purchase) {
|
||||
$user->update(['server_limit' => $this->server_limit_after_irl_purchase]);
|
||||
if (config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE') !== 0 && $user->server_limit < config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')) {
|
||||
$user->update(['server_limit' => config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')]);
|
||||
}
|
||||
|
||||
//update User with bought item
|
||||
|
@ -65,17 +40,17 @@ class UserPayment
|
|||
}
|
||||
|
||||
//give referral commission always
|
||||
if (($this->referral_mode === "commission" || $this->referral_mode === "both") && $shopProduct->type == "Credits" && $this->referral_always_give_commission) {
|
||||
if ((config("SETTINGS::REFERRAL:MODE") == "commission" || config("SETTINGS::REFERRAL:MODE") == "both") && $shopProduct->type == "Credits" && config("SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION") == "true") {
|
||||
if ($ref_user = DB::table("user_referrals")->where('registered_user_id', '=', $user->id)->first()) {
|
||||
$ref_user = User::findOrFail($ref_user->referral_id);
|
||||
$increment = number_format($shopProduct->quantity * (PartnerDiscount::getCommission($ref_user->id, $this->referral_percentage)) / 100, 0, "", "");
|
||||
$increment = number_format($shopProduct->quantity * (PartnerDiscount::getCommission($ref_user->id)) / 100, 0, "", "");
|
||||
$ref_user->increment('credits', $increment);
|
||||
|
||||
//LOGS REFERRALS IN THE ACTIVITY LOG
|
||||
activity()
|
||||
->performedOn($user)
|
||||
->causedBy($ref_user)
|
||||
->log('gained ' . $increment . ' ' . $this->credits_display_name . ' for commission-referral of ' . $user->name . ' (ID:' . $user->id . ')');
|
||||
->log('gained ' . $increment . ' ' . config("SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME") . ' for commission-referral of ' . $user->name . ' (ID:' . $user->id . ')');
|
||||
}
|
||||
}
|
||||
//update role give Referral-reward
|
||||
|
@ -83,17 +58,17 @@ class UserPayment
|
|||
$user->update(['role' => 'client']);
|
||||
|
||||
//give referral commission only on first purchase
|
||||
if (($this->referral_mode === "commission" || $this->referral_mode === "both") && $shopProduct->type == "Credits" && !$this->referral_always_give_commission) {
|
||||
if ((config("SETTINGS::REFERRAL:MODE") == "commission" || config("SETTINGS::REFERRAL:MODE") == "both") && $shopProduct->type == "Credits" && config("SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION") == "false") {
|
||||
if ($ref_user = DB::table("user_referrals")->where('registered_user_id', '=', $user->id)->first()) {
|
||||
$ref_user = User::findOrFail($ref_user->referral_id);
|
||||
$increment = number_format($shopProduct->quantity * (PartnerDiscount::getCommission($ref_user->id, $this->referral_percentage)) / 100, 0, "", "");
|
||||
$increment = number_format($shopProduct->quantity * (PartnerDiscount::getCommission($ref_user->id)) / 100, 0, "", "");
|
||||
$ref_user->increment('credits', $increment);
|
||||
|
||||
//LOGS REFERRALS IN THE ACTIVITY LOG
|
||||
activity()
|
||||
->performedOn($user)
|
||||
->causedBy($ref_user)
|
||||
->log('gained ' . $increment . ' ' . $this->credits_display_name . ' for commission-referral of ' . $user->name . ' (ID:' . $user->id . ')');
|
||||
->log('gained ' . $increment . ' ' . config("SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME") . ' for commission-referral of ' . $user->name . ' (ID:' . $user->id . ')');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,23 +2,16 @@
|
|||
|
||||
namespace App\Listeners;
|
||||
|
||||
use App\Settings\UserSettings;
|
||||
|
||||
class Verified
|
||||
{
|
||||
private $server_limit_after_verify_email;
|
||||
|
||||
private $credits_reward_after_verify_email;
|
||||
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(UserSettings $user_settings)
|
||||
public function __construct()
|
||||
{
|
||||
$this->server_limit_after_verify_email = $user_settings->server_limit_after_verify_email;
|
||||
$this->credits_reward_after_verify_email = $user_settings->credits_reward_after_verify_email;
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,8 +23,8 @@ class Verified
|
|||
public function handle($event)
|
||||
{
|
||||
if (! $event->user->email_verified_reward) {
|
||||
$event->user->increment('server_limit', $this->server_limit_after_verify_email);
|
||||
$event->user->increment('credits', $this->credits_reward_after_verify_email);
|
||||
$event->user->increment('server_limit', config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL'));
|
||||
$event->user->increment('credits', config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models\Pterodactyl;
|
||||
namespace App\Models;
|
||||
|
||||
use App\Classes\PterodactylClient;
|
||||
use App\Classes\Pterodactyl;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use App\Models\Pterodactyl\Nest;
|
||||
use App\Models\Product;
|
||||
|
||||
class Egg extends Model
|
||||
{
|
||||
|
@ -39,9 +37,9 @@ class Egg extends Model
|
|||
public static function syncEggs()
|
||||
{
|
||||
Nest::syncNests();
|
||||
$client = app(PterodactylClient::class);
|
||||
Nest::all()->each(function (Nest $nest) use ($client) {
|
||||
$eggs = $client->getEggs($nest);
|
||||
|
||||
Nest::all()->each(function (Nest $nest) {
|
||||
$eggs = Pterodactyl::getEggs($nest);
|
||||
|
||||
foreach ($eggs as $egg) {
|
||||
$array = [];
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models\Pterodactyl;
|
||||
namespace App\Models;
|
||||
|
||||
use App\Classes\PterodactylClient;
|
||||
use App\Classes\Pterodactyl;
|
||||
use Exception;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
@ -33,8 +33,7 @@ class Location extends Model
|
|||
*/
|
||||
public static function syncLocations()
|
||||
{
|
||||
$client = app(PterodactylClient::class);
|
||||
$locations = $client->getLocations();
|
||||
$locations = Pterodactyl::getLocations();
|
||||
|
||||
//map response
|
||||
$locations = array_map(function ($val) {
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models\Pterodactyl;
|
||||
namespace App\Models;
|
||||
|
||||
use App\Classes\PterodactylClient;
|
||||
use App\Classes\Pterodactyl;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
|
@ -32,8 +32,7 @@ class Nest extends Model
|
|||
|
||||
public static function syncNests()
|
||||
{
|
||||
$client = app(PterodactylClient::class);
|
||||
$nests = $client->getNests();
|
||||
$nests = Pterodactyl::getNests();
|
||||
|
||||
//map response
|
||||
$nests = array_map(function ($nest) {
|
|
@ -1,14 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models\Pterodactyl;
|
||||
namespace App\Models;
|
||||
|
||||
use App\Classes\PterodactylClient;
|
||||
use App\Classes\Pterodactyl;
|
||||
use Exception;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use App\Models\Product;
|
||||
|
||||
class Node extends Model
|
||||
{
|
||||
|
@ -33,8 +32,7 @@ class Node extends Model
|
|||
public static function syncNodes()
|
||||
{
|
||||
Location::syncLocations();
|
||||
$client = app(PterodactylClient::class);
|
||||
$nodes = $client->getNodes();
|
||||
$nodes = Pterodactyl::getNodes();
|
||||
|
||||
//map response
|
||||
$nodes = array_map(function ($node) {
|
|
@ -33,7 +33,7 @@ class PartnerDiscount extends Model
|
|||
return 0;
|
||||
}
|
||||
|
||||
public static function getCommission($user_id, $percentage)
|
||||
public static function getCommission($user_id)
|
||||
{
|
||||
if ($partnerDiscount = PartnerDiscount::where('user_id', $user_id)->first()) {
|
||||
if ($partnerDiscount->referral_system_commission >= 0) {
|
||||
|
@ -41,6 +41,6 @@ class PartnerDiscount extends Model
|
|||
}
|
||||
}
|
||||
|
||||
return $percentage;
|
||||
return config('SETTINGS::REFERRAL:PERCENTAGE');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Spatie\Activitylog\LogOptions;
|
||||
use Spatie\Activitylog\Traits\LogsActivity;
|
||||
use App\Models\Pterodactyl\Egg;
|
||||
use App\Models\Pterodactyl\Node;
|
||||
|
||||
class Product extends Model
|
||||
{
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Classes\PterodactylClient;
|
||||
use App\Settings\PterodactylSettings;
|
||||
use App\Classes\Pterodactyl;
|
||||
use Exception;
|
||||
use GuzzleHttp\Promise\PromiseInterface;
|
||||
use Hidehalo\Nanoid\Client;
|
||||
|
@ -22,17 +21,13 @@ class Server extends Model
|
|||
{
|
||||
use HasFactory;
|
||||
use LogsActivity;
|
||||
|
||||
private PterodactylClient $pterodactyl;
|
||||
|
||||
public function getActivitylogOptions(): LogOptions
|
||||
{
|
||||
return LogOptions::defaults()
|
||||
->logOnlyDirty()
|
||||
->logOnly(['*'])
|
||||
->dontSubmitEmptyLogs();
|
||||
-> logOnlyDirty()
|
||||
-> logOnly(['*'])
|
||||
-> dontSubmitEmptyLogs();
|
||||
}
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
|
@ -67,12 +62,6 @@ class Server extends Model
|
|||
'suspended' => 'datetime',
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$ptero_settings = new PterodactylSettings();
|
||||
$this->pterodactyl = new PterodactylClient($ptero_settings);
|
||||
}
|
||||
|
||||
public static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
@ -84,8 +73,8 @@ class Server extends Model
|
|||
});
|
||||
|
||||
static::deleting(function (Server $server) {
|
||||
$response = $server->pterodactyl->application->delete("/application/servers/{$server->pterodactyl_id}");
|
||||
if ($response->failed() && !is_null($server->pterodactyl_id)) {
|
||||
$response = Pterodactyl::client()->delete("/application/servers/{$server->pterodactyl_id}");
|
||||
if ($response->failed() && ! is_null($server->pterodactyl_id)) {
|
||||
//only return error when it's not a 404 error
|
||||
if ($response['errors'][0]['status'] != '404') {
|
||||
throw new Exception($response['errors'][0]['code']);
|
||||
|
@ -99,7 +88,7 @@ class Server extends Model
|
|||
*/
|
||||
public function isSuspended()
|
||||
{
|
||||
return !is_null($this->suspended);
|
||||
return ! is_null($this->suspended);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,7 +96,7 @@ class Server extends Model
|
|||
*/
|
||||
public function getPterodactylServer()
|
||||
{
|
||||
return $this->pterodactyl->application->get("/application/servers/{$this->pterodactyl_id}");
|
||||
return Pterodactyl::client()->get("/application/servers/{$this->pterodactyl_id}");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,7 +104,7 @@ class Server extends Model
|
|||
*/
|
||||
public function suspend()
|
||||
{
|
||||
$response = $this->pterodactyl->suspendServer($this);
|
||||
$response = Pterodactyl::suspendServer($this);
|
||||
|
||||
if ($response->successful()) {
|
||||
$this->update([
|
||||
|
@ -131,7 +120,7 @@ class Server extends Model
|
|||
*/
|
||||
public function unSuspend()
|
||||
{
|
||||
$response = $this->pterodactyl->unSuspendServer($this);
|
||||
$response = Pterodactyl::unSuspendServer($this);
|
||||
|
||||
if ($response->successful()) {
|
||||
$this->update([
|
||||
|
|
|
@ -4,8 +4,48 @@ namespace App\Models;
|
|||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class Settings extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'settings';
|
||||
|
||||
public const CACHE_TAG = 'setting';
|
||||
|
||||
public $primaryKey = 'key';
|
||||
|
||||
public $incrementing = false;
|
||||
|
||||
protected $keyType = 'string';
|
||||
|
||||
protected $fillable = [
|
||||
'key',
|
||||
'value',
|
||||
'type',
|
||||
];
|
||||
|
||||
public static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::updated(function (Settings $settings) {
|
||||
Cache::forget(self::CACHE_TAG.':'.$settings->key);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param $default
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getValueByKey(string $key, $default = null)
|
||||
{
|
||||
return Cache::rememberForever(self::CACHE_TAG.':'.$key, function () use ($default, $key) {
|
||||
$settings = self::find($key);
|
||||
|
||||
return $settings ? $settings->value : $default;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,9 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Classes\Pterodactyl;
|
||||
use App\Notifications\Auth\QueuedVerifyEmail;
|
||||
use App\Notifications\WelcomeMessage;
|
||||
use App\Settings\GeneralSettings;
|
||||
use App\Settings\UserSettings;
|
||||
use App\Classes\PterodactylClient;
|
||||
use App\Settings\PterodactylSettings;
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
|
@ -26,8 +23,6 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||
{
|
||||
use HasFactory, Notifiable, LogsActivity, CausesActivity;
|
||||
|
||||
private PterodactylClient $pterodactyl;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
|
@ -90,18 +85,12 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||
'server_limit' => 'float',
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$ptero_settings = new PterodactylSettings();
|
||||
$this->pterodactyl = new PterodactylClient($ptero_settings);
|
||||
}
|
||||
|
||||
public static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::created(function (User $user, GeneralSettings $general_settings, UserSettings $user_settings) {
|
||||
$user->notify(new WelcomeMessage($user, $general_settings, $user_settings));
|
||||
static::created(function (User $user) {
|
||||
$user->notify(new WelcomeMessage($user));
|
||||
});
|
||||
|
||||
static::deleting(function (User $user) {
|
||||
|
@ -122,7 +111,7 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||
|
||||
$user->discordUser()->delete();
|
||||
|
||||
$user->pterodactyl->application->delete("/application/users/{$user->pterodactyl_id}");
|
||||
Pterodactyl::client()->delete("/application/users/{$user->pterodactyl_id}");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -195,6 +184,9 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||
return $this->suspended;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function suspend()
|
||||
{
|
||||
foreach ($this->servers as $server) {
|
||||
|
@ -208,6 +200,9 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function unSuspend()
|
||||
{
|
||||
foreach ($this->getServersWithProduct() as $server) {
|
||||
|
@ -235,9 +230,23 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||
*/
|
||||
public function getAvatar()
|
||||
{
|
||||
//TODO loading the images to confirm they exist is causing to much load time. alternative has to be found :) maybe onerror tag on the <img tags>
|
||||
// if ($this->discordUser()->exists()) {
|
||||
// if(@getimagesize($this->discordUser->getAvatar())) {
|
||||
// $avatar = $this->discordUser->getAvatar();
|
||||
// } else {
|
||||
// $avatar = "https://www.gravatar.com/avatar/" . md5(strtolower(trim($this->email)));
|
||||
// }
|
||||
// } else {
|
||||
// $avatar = "https://www.gravatar.com/avatar/" . md5(strtolower(trim($this->email)));
|
||||
// }
|
||||
|
||||
return 'https://www.gravatar.com/avatar/' . md5(strtolower(trim($this->email)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function creditUsage()
|
||||
{
|
||||
$usage = 0;
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
namespace App\Notifications;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Settings\GeneralSettings;
|
||||
use App\Settings\ReferralSettings;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
|
@ -17,8 +15,6 @@ class ReferralNotification extends Notification
|
|||
*/
|
||||
private $user;
|
||||
|
||||
private $ref_user;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
|
@ -47,13 +43,13 @@ class ReferralNotification extends Notification
|
|||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable, GeneralSettings $general_settings, ReferralSettings $referral_settings)
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
return [
|
||||
'title' => __('Someone registered using your Code!'),
|
||||
'content' => '
|
||||
<p>You received '. $referral_settings->reward . ' ' . $general_settings->credits_display_name . '</p>
|
||||
<p>because ' . $this->ref_user->name . ' registered with your Referral-Code!</p>
|
||||
<p>You received '.config('SETTINGS::REFERRAL::REWARD').' '.config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME').'</p>
|
||||
<p>because '.$this->ref_user->name.' registered with your Referral-Code!</p>
|
||||
<p>Thank you very much for supporting us!.</p>
|
||||
<p>'.config('app.name', 'Laravel').'</p>
|
||||
',
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
namespace App\Notifications;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Settings\GeneralSettings;
|
||||
use App\Settings\UserSettings;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
@ -18,29 +16,14 @@ class WelcomeMessage extends Notification implements ShouldQueue
|
|||
*/
|
||||
private $user;
|
||||
|
||||
private $credits_display_name;
|
||||
|
||||
private $credits_reward_after_verify_discord;
|
||||
|
||||
private $credits_reward_after_verify_email;
|
||||
|
||||
private $server_limit_after_verify_discord;
|
||||
|
||||
private $server_limit_after_verify_email;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function __construct(User $user, GeneralSettings $general_settings, UserSettings $user_settings)
|
||||
public function __construct(User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->credits_display_name = $general_settings->credits_display_name;
|
||||
$this->credits_reward_after_verify_discord = $user_settings->credits_reward_after_verify_discord;
|
||||
$this->credits_reward_after_verify_email = $user_settings->credits_reward_after_verify_email;
|
||||
$this->server_limit_after_verify_discord = $user_settings->server_limit_after_verify_discord;
|
||||
$this->server_limit_after_verify_email = $user_settings->server_limit_after_verify_email;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,18 +40,18 @@ class WelcomeMessage extends Notification implements ShouldQueue
|
|||
public function AdditionalLines()
|
||||
{
|
||||
$AdditionalLine = '';
|
||||
if ($this->credits_reward_after_verify_email != 0) {
|
||||
$AdditionalLine .= __('Verifying your e-mail address will grant you ').$this->credits_reward_after_verify_email.' '.__('additional').' '.$this->credits_display_name.'. <br />';
|
||||
if (config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL') != 0) {
|
||||
$AdditionalLine .= __('Verifying your e-mail address will grant you ').config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL').' '.__('additional').' '.config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME').'. <br />';
|
||||
}
|
||||
if ($this->server_limit_after_verify_email != 0) {
|
||||
$AdditionalLine .= __('Verifying your e-mail will also increase your Server Limit by ').$this->server_limit_after_verify_email.'. <br />';
|
||||
if (config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL') != 0) {
|
||||
$AdditionalLine .= __('Verifying your e-mail will also increase your Server Limit by ').config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL').'. <br />';
|
||||
}
|
||||
$AdditionalLine .= '<br />';
|
||||
if ($this->credits_reward_after_verify_discord != 0) {
|
||||
$AdditionalLine .= __('You can also verify your discord account to get another ').$this->credits_reward_after_verify_discord.' '.$this->credits_display_name.'. <br />';
|
||||
if (config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD') != 0) {
|
||||
$AdditionalLine .= __('You can also verify your discord account to get another ').config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD').' '.config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME').'. <br />';
|
||||
}
|
||||
if ($this->server_limit_after_verify_discord != 0) {
|
||||
$AdditionalLine .= __('Verifying your Discord account will also increase your Server Limit by ').$this->server_limit_after_verify_discord.'. <br />';
|
||||
if (config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD') != 0) {
|
||||
$AdditionalLine .= __('Verifying your Discord account will also increase your Server Limit by ').config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD').'. <br />';
|
||||
}
|
||||
|
||||
return $AdditionalLine;
|
||||
|
|
|
@ -2,17 +2,16 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Extensions\PaymentGateways\PayPal\PayPalSettings;
|
||||
use App\Models\Settings;
|
||||
use App\Models\UsefulLink;
|
||||
use App\Settings\MailSettings;
|
||||
use Exception;
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
use Qirolab\Theme\Theme;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
@ -55,14 +54,6 @@ class AppServiceProvider extends ServiceProvider
|
|||
return $ok;
|
||||
});
|
||||
|
||||
// Force HTTPS if APP_URL is set to https
|
||||
if (config('app.url') && parse_url(config('app.url'), PHP_URL_SCHEME) === 'https') {
|
||||
URL::forceScheme('https');
|
||||
}
|
||||
|
||||
// Do not run this code if no APP_KEY is set
|
||||
if (config('app.key') == null) return;
|
||||
|
||||
try {
|
||||
if (Schema::hasColumn('useful_links', 'position')) {
|
||||
$useful_links = UsefulLink::where("position", "like", "%topbar%")->get()->sortby("id");
|
||||
|
@ -72,8 +63,92 @@ class AppServiceProvider extends ServiceProvider
|
|||
Log::error("Couldnt find useful_links. Probably the installation is not completet. " . $e);
|
||||
}
|
||||
|
||||
//only run if the installer has been executed
|
||||
try {
|
||||
$settings = Settings::all();
|
||||
// Set all configs from database
|
||||
foreach ($settings as $setting) {
|
||||
config([$setting->key => $setting->value]);
|
||||
}
|
||||
|
||||
$settings = $this->app->make(MailSettings::class);
|
||||
$settings->setConfig();
|
||||
if (!file_exists(base_path('themes') . "/" . config("SETTINGS::SYSTEM:THEME"))) {
|
||||
config(['SETTINGS::SYSTEM:THEME' => "default"]);
|
||||
}
|
||||
|
||||
if (config('SETTINGS::SYSTEM:THEME') && config('SETTINGS::SYSTEM:THEME') !== config('theme.active')) {
|
||||
Theme::set(config("SETTINGS::SYSTEM:THEME", "default"), "default");
|
||||
} else {
|
||||
Theme::set("default", "default");
|
||||
}
|
||||
|
||||
// Set Mail Config
|
||||
//only update config if mail settings have changed in DB
|
||||
if (
|
||||
config('mail.default') != config('SETTINGS:MAIL:MAILER') ||
|
||||
config('mail.mailers.smtp.host') != config('SETTINGS:MAIL:HOST') ||
|
||||
config('mail.mailers.smtp.port') != config('SETTINGS:MAIL:PORT') ||
|
||||
config('mail.mailers.smtp.username') != config('SETTINGS:MAIL:USERNAME') ||
|
||||
config('mail.mailers.smtp.password') != config('SETTINGS:MAIL:PASSWORD') ||
|
||||
config('mail.mailers.smtp.encryption') != config('SETTINGS:MAIL:ENCRYPTION') ||
|
||||
config('mail.from.address') != config('SETTINGS:MAIL:FROM_ADDRESS') ||
|
||||
config('mail.from.name') != config('SETTINGS:MAIL:FROM_NAME')
|
||||
) {
|
||||
config(['mail.default' => config('SETTINGS::MAIL:MAILER')]);
|
||||
config(['mail.mailers.smtp' => [
|
||||
'transport' => 'smtp',
|
||||
'host' => config('SETTINGS::MAIL:HOST'),
|
||||
'port' => config('SETTINGS::MAIL:PORT'),
|
||||
'encryption' => config('SETTINGS::MAIL:ENCRYPTION'),
|
||||
'username' => config('SETTINGS::MAIL:USERNAME'),
|
||||
'password' => config('SETTINGS::MAIL:PASSWORD'),
|
||||
'timeout' => null,
|
||||
'auth_mode' => null,
|
||||
]]);
|
||||
config(['mail.from' => ['address' => config('SETTINGS::MAIL:FROM_ADDRESS'), 'name' => config('SETTINGS::MAIL:FROM_NAME')]]);
|
||||
|
||||
Artisan::call('queue:restart');
|
||||
}
|
||||
|
||||
// Set Recaptcha API Config
|
||||
// Load recaptcha package if recaptcha is enabled
|
||||
if (config('SETTINGS::RECAPTCHA:ENABLED') == 'true') {
|
||||
$this->app->register(\Biscolab\ReCaptcha\ReCaptchaServiceProvider::class);
|
||||
}
|
||||
|
||||
//only update config if recaptcha settings have changed in DB
|
||||
if (
|
||||
config('recaptcha.api_site_key') != config('SETTINGS::RECAPTCHA:SITE_KEY') ||
|
||||
config('recaptcha.api_secret_key') != config('SETTINGS::RECAPTCHA:SECRET_KEY')
|
||||
) {
|
||||
config(['recaptcha.api_site_key' => config('SETTINGS::RECAPTCHA:SITE_KEY')]);
|
||||
config(['recaptcha.api_secret_key' => config('SETTINGS::RECAPTCHA:SECRET_KEY')]);
|
||||
|
||||
Artisan::call('config:clear');
|
||||
Artisan::call('cache:clear');
|
||||
}
|
||||
|
||||
try {
|
||||
$stringfromfile = file(base_path() . '/.git/HEAD');
|
||||
|
||||
$firstLine = $stringfromfile[0]; //get the string from the array
|
||||
|
||||
$explodedstring = explode('/', $firstLine, 3); //seperate out by the "/" in the string
|
||||
|
||||
$branchname = $explodedstring[2]; //get the one that is always the branch name
|
||||
} catch (Exception $e) {
|
||||
$branchname = 'unknown';
|
||||
Log::notice($e);
|
||||
}
|
||||
config(['BRANCHNAME' => $branchname]);
|
||||
|
||||
// Set Discord-API Config
|
||||
config(['services.discord.client_id' => config('SETTINGS::DISCORD:CLIENT_ID')]);
|
||||
config(['services.discord.client_secret' => config('SETTINGS::DISCORD:CLIENT_SECRET')]);
|
||||
} catch (Exception $e) {
|
||||
error_log('Settings Error: Could not load settings from database. The Installation probably is not done yet.');
|
||||
error_log($e);
|
||||
Log::error('Settings Error: Could not load settings from database. The Installation probably is not done yet.');
|
||||
Log::error($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class DiscordSettings extends Settings
|
||||
{
|
||||
public ?string $bot_token;
|
||||
public ?string $client_id;
|
||||
public ?string $client_secret;
|
||||
public ?string $guild_id;
|
||||
public ?string $invite_url;
|
||||
public ?string $role_id;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'discord';
|
||||
}
|
||||
|
||||
public static function encrypted(): array
|
||||
{
|
||||
return [
|
||||
'bot_token',
|
||||
'client_id',
|
||||
'client_secret'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of validations array
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function getValidations()
|
||||
{
|
||||
return [
|
||||
'bot_token' => 'nullable|string',
|
||||
'client_id' => 'nullable|string',
|
||||
'client_secret' => 'nullable|string',
|
||||
'guild_id' => 'nullable|string',
|
||||
'invite_url' => 'nullable|string|url',
|
||||
'role_id' => 'nullable|string',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of optionInputData array
|
||||
* Only used for the settings page
|
||||
* @return array<array<'type'|'label'|'description'|'options', string|bool|float|int|array<string, string>>>
|
||||
*/
|
||||
public static function getOptionInputData()
|
||||
{
|
||||
return [
|
||||
'category_icon' => 'fas fa-user-friends',
|
||||
'bot_token' => [
|
||||
'label' => 'Bot Token',
|
||||
'type' => 'string',
|
||||
'description' => 'The bot token for your Discord bot.',
|
||||
],
|
||||
'client_id' => [
|
||||
'label' => 'Client ID',
|
||||
'type' => 'string',
|
||||
'description' => 'The client ID for your Discord bot.',
|
||||
],
|
||||
'client_secret' => [
|
||||
'label' => 'Client Secret',
|
||||
'type' => 'string',
|
||||
'description' => 'The client secret for your Discord bot.',
|
||||
],
|
||||
'guild_id' => [
|
||||
'label' => 'Guild ID',
|
||||
'type' => 'string',
|
||||
'description' => 'The guild ID for your Discord server.',
|
||||
],
|
||||
'invite_url' => [
|
||||
'label' => 'Invite URL',
|
||||
'type' => 'string',
|
||||
'description' => 'The invite URL for your Discord server.',
|
||||
],
|
||||
'role_id' => [
|
||||
'label' => 'Role ID',
|
||||
'type' => 'string',
|
||||
'description' => 'The role ID for your Discord server.',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class GeneralSettings extends Settings
|
||||
{
|
||||
public bool $store_enabled;
|
||||
public string $credits_display_name;
|
||||
public bool $recaptcha_enabled;
|
||||
public string $recaptcha_site_key;
|
||||
public string $recaptcha_secret_key;
|
||||
public string $phpmyadmin_url;
|
||||
public bool $alert_enabled;
|
||||
public string $alert_type;
|
||||
public string $alert_message;
|
||||
public string $theme;
|
||||
|
||||
//public int $initial_user_role; wait for Roles & Permissions PR.
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'general';
|
||||
}
|
||||
|
||||
public static function encrypted(): array
|
||||
{
|
||||
return [
|
||||
'recaptcha_site_key',
|
||||
'recaptcha_secret_key'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of validations array
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function getValidations()
|
||||
{
|
||||
return [
|
||||
'store_enabled' => 'boolean',
|
||||
'credits_display_name' => 'required|string',
|
||||
'recaptcha_enabled' => 'nullable|boolean',
|
||||
'recaptcha_site_key' => 'nullable|string',
|
||||
'recaptcha_secret_key' => 'nullable|string',
|
||||
'phpmyadmin_url' => 'nullable|string',
|
||||
'alert_enabled' => 'nullable|boolean',
|
||||
'alert_type' => 'required|in:primary,secondary,success,danger,warning,info',
|
||||
'alert_message' => 'required|string',
|
||||
'theme' => 'required|in:default,BlueInfinity' // TODO: themes should be made/loaded dynamically
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of optionTypes
|
||||
* Only used for the settings page
|
||||
* @return array<array<'type'|'label'|'description'|'options', string|bool|float|int|array<string, string>>>
|
||||
*/
|
||||
public static function getOptionInputData()
|
||||
{
|
||||
return [
|
||||
'category_icon' => "fas fa-cog",
|
||||
'store_enabled' => [
|
||||
'type' => 'boolean',
|
||||
'label' => 'Enable Store',
|
||||
'description' => 'Enable the store for users to purchase credits.'
|
||||
],
|
||||
'credits_display_name' => [
|
||||
'type' => 'string',
|
||||
'label' => 'Credits Display Name',
|
||||
'description' => 'The name of the currency used.'
|
||||
],
|
||||
'initial_user_credits' => [
|
||||
'type' => 'number',
|
||||
'label' => 'Initial User Credits',
|
||||
'description' => 'The amount of credits a user gets when they register.'
|
||||
],
|
||||
'initial_server_limit' => [
|
||||
'type' => 'number',
|
||||
'label' => 'Initial Server Limit',
|
||||
'description' => 'The amount of servers a user can create when they register.'
|
||||
],
|
||||
'recaptcha_enabled' => [
|
||||
'type' => 'boolean',
|
||||
'label' => 'Enable reCAPTCHA',
|
||||
'description' => 'Enable reCAPTCHA on the login page.'
|
||||
],
|
||||
'recaptcha_site_key' => [
|
||||
'type' => 'string',
|
||||
'label' => 'reCAPTCHA Site Key',
|
||||
'description' => 'The site key for reCAPTCHA.'
|
||||
],
|
||||
'recaptcha_secret_key' => [
|
||||
'type' => 'string',
|
||||
'label' => 'reCAPTCHA Secret Key',
|
||||
'description' => 'The secret key for reCAPTCHA.'
|
||||
],
|
||||
'phpmyadmin_url' => [
|
||||
'type' => 'string',
|
||||
'label' => 'phpMyAdmin URL',
|
||||
'description' => 'The URL of your phpMyAdmin installation.'
|
||||
],
|
||||
'alert_enabled' => [
|
||||
'type' => 'boolean',
|
||||
'label' => 'Enable Alert',
|
||||
'description' => 'Enable an alert to be displayed on the home page.'
|
||||
],
|
||||
'alert_type' => [
|
||||
'type' => 'select',
|
||||
'label' => 'Alert Type',
|
||||
'options' => [
|
||||
'primary' => 'Blue',
|
||||
'secondary' => 'Grey',
|
||||
'success' => 'Green',
|
||||
'danger' => 'Red',
|
||||
'warning' => 'Orange',
|
||||
'info' => 'Cyan',
|
||||
],
|
||||
'description' => 'The type of alert to display.'
|
||||
],
|
||||
'alert_message' => [
|
||||
'type' => 'string',
|
||||
'label' => 'Alert Message',
|
||||
'description' => 'The message to display in the alert.'
|
||||
],
|
||||
'theme' => [
|
||||
'type' => 'select',
|
||||
'label' => 'Theme',
|
||||
'options' => [
|
||||
'default' => 'Default',
|
||||
'BlueInfinity' => 'Blue Infinity',
|
||||
], // TODO: themes should be made/loaded dynamically
|
||||
'description' => 'The theme to use for the site.'
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class InvoiceSettings extends Settings
|
||||
{
|
||||
public ?string $company_address;
|
||||
public ?string $company_mail;
|
||||
public ?string $company_name;
|
||||
public ?string $company_phone;
|
||||
public ?string $company_vat;
|
||||
public ?string $company_website;
|
||||
public bool $enabled;
|
||||
public ?string $prefix;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'invoice';
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of validations array
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function getValidations()
|
||||
{
|
||||
return [
|
||||
'company_address' => 'nullable|string',
|
||||
'company_mail' => 'nullable|string',
|
||||
'company_name' => 'nullable|string',
|
||||
'company_phone' => 'nullable|string',
|
||||
'company_vat' => 'nullable|string',
|
||||
'company_website' => 'nullable|string',
|
||||
'enabled' => 'nullable|boolean',
|
||||
'prefix' => 'nullable|string',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of optionTypes
|
||||
* Only used for the settings page
|
||||
* @return array<array<'type'|'label'|'description'|'options', string|bool|float|int|array<string, string>>>
|
||||
*/
|
||||
public static function getOptionInputData()
|
||||
{
|
||||
return [
|
||||
'category_icon' => 'fas fa-file-invoice-dollar',
|
||||
'company_address' => [
|
||||
'label' => 'Company Address',
|
||||
'type' => 'string',
|
||||
'description' => 'The address of your company.',
|
||||
],
|
||||
'company_mail' => [
|
||||
'label' => 'Company Mail',
|
||||
'type' => 'string',
|
||||
'description' => 'The mail of your company.',
|
||||
],
|
||||
'company_name' => [
|
||||
'label' => 'Company Name',
|
||||
'type' => 'string',
|
||||
'description' => 'The name of your company.',
|
||||
],
|
||||
'company_phone' => [
|
||||
'label' => 'Company Phone',
|
||||
'type' => 'string',
|
||||
'description' => 'The phone of your company.',
|
||||
],
|
||||
'company_vat' => [
|
||||
'label' => 'Company VAT ID',
|
||||
'type' => 'string',
|
||||
'description' => 'The VAT ID of your company.',
|
||||
],
|
||||
'company_website' => [
|
||||
'label' => 'Company Website',
|
||||
'type' => 'string',
|
||||
'description' => 'The website of your company.',
|
||||
],
|
||||
'enabled' => [
|
||||
'label' => 'Enabled',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enable or disable invoices.',
|
||||
],
|
||||
'prefix' => [
|
||||
'label' => 'Prefix',
|
||||
'type' => 'string',
|
||||
'description' => 'The prefix of your invoices.',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class LocaleSettings extends Settings
|
||||
{
|
||||
public ?string $available;
|
||||
public bool $clients_can_change;
|
||||
public ?string $datatables;
|
||||
public string $default;
|
||||
public bool $dynamic;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'locale';
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of validations array
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function getValidations()
|
||||
{
|
||||
return [
|
||||
'available' => 'nullable|array',
|
||||
'clients_can_change' => 'nullable|boolean',
|
||||
'datatables' => 'nullable|string',
|
||||
'default' => 'required|in:' . implode(',', config('app.available_locales')),
|
||||
'dynamic' => 'nullable|boolean',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of optionTypes
|
||||
* Only used for the settings page
|
||||
* @return array<array<'type'|'label'|'description'|'options', string|bool|float|int|array<string, string>>>
|
||||
*/
|
||||
public static function getOptionInputData()
|
||||
{
|
||||
return [
|
||||
'category_icon' => 'fas fa-globe',
|
||||
'available' => [
|
||||
'label' => 'Available Locales',
|
||||
'type' => 'multiselect',
|
||||
'description' => 'The locales that are available for the user to choose from.',
|
||||
'options' => config('app.available_locales'),
|
||||
],
|
||||
'clients_can_change' => [
|
||||
'label' => 'Clients Can Change',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Whether clients can change their locale.',
|
||||
],
|
||||
'datatables' => [
|
||||
'label' => 'Datatables Locale',
|
||||
'type' => 'string',
|
||||
'description' => 'The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: <a href="https://datatables.net/plug-ins/i18n/">https://datatables.net/plug-ins/i18n/</a>',
|
||||
],
|
||||
'default' => [
|
||||
'label' => 'Default Locale',
|
||||
'type' => 'select',
|
||||
'description' => 'The default locale to use.',
|
||||
'options' => config('app.available_locales'),
|
||||
],
|
||||
'dynamic' => [
|
||||
'label' => 'Dynamic Locale',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Whether to use the dynamic locale.',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class MailSettings extends Settings
|
||||
{
|
||||
public ?string $mail_host;
|
||||
public ?int $mail_port;
|
||||
public ?string $mail_username;
|
||||
public ?string $mail_password;
|
||||
public ?string $mail_encryption;
|
||||
public ?string $mail_from_address;
|
||||
public ?string $mail_from_name;
|
||||
public ?string $mail_mailer;
|
||||
public bool $mail_enabled;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'mail';
|
||||
}
|
||||
|
||||
public static function encrypted(): array
|
||||
{
|
||||
return [
|
||||
'mail_password'
|
||||
];
|
||||
}
|
||||
|
||||
public function setConfig()
|
||||
{
|
||||
try {
|
||||
config()->set('mail.mailers.smtp.host', $this->mail_host);
|
||||
config()->set('mail.mailers.smtp.port', $this->mail_port);
|
||||
config()->set('mail.mailers.smtp.encryption', $this->mail_encryption);
|
||||
config()->set('mail.mailers.smtp.username', $this->mail_username);
|
||||
config()->set('mail.mailers.smtp.password', $this->mail_password);
|
||||
config()->set('mail.from.address', $this->mail_from_address);
|
||||
config()->set('mail.from.name', $this->mail_from_name);
|
||||
} catch (\Exception) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of validations array
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function getValidations()
|
||||
{
|
||||
return [
|
||||
'mail_host' => 'nullable|string',
|
||||
'mail_port' => 'nullable|int',
|
||||
'mail_username' => 'nullable|string',
|
||||
'mail_password' => 'nullable|string',
|
||||
'mail_encryption' => 'nullable|string',
|
||||
'mail_from_address' => 'nullable|string',
|
||||
'mail_from_name' => 'nullable|string',
|
||||
'mail_mailer' => 'nullable|string',
|
||||
'mail_enabled' => 'nullable|boolean',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of optionTypes
|
||||
* Only used for the settings page
|
||||
* @return array<array<'type'|'label'|'description'|'options', string|bool|float|int|array<string, string>>>
|
||||
*/
|
||||
public static function getOptionInputData()
|
||||
{
|
||||
return [
|
||||
'category_icon' => 'fas fa-envelope',
|
||||
'mail_host' => [
|
||||
'label' => 'Mail Host',
|
||||
'type' => 'string',
|
||||
'description' => 'The host of your mail server.',
|
||||
],
|
||||
'mail_port' => [
|
||||
'label' => 'Mail Port',
|
||||
'type' => 'number',
|
||||
'description' => 'The port of your mail server.',
|
||||
],
|
||||
'mail_username' => [
|
||||
'label' => 'Mail Username',
|
||||
'type' => 'string',
|
||||
'description' => 'The username of your mail server.',
|
||||
],
|
||||
'mail_password' => [
|
||||
'label' => 'Mail Password',
|
||||
'type' => 'string',
|
||||
'description' => 'The password of your mail server.',
|
||||
],
|
||||
'mail_encryption' => [
|
||||
'label' => 'Mail Encryption',
|
||||
'type' => 'string',
|
||||
'description' => 'The encryption of your mail server.',
|
||||
],
|
||||
'mail_from_address' => [
|
||||
'label' => 'Mail From Address',
|
||||
'type' => 'string',
|
||||
'description' => 'The from address of your mail server.',
|
||||
],
|
||||
'mail_from_name' => [
|
||||
'label' => 'Mail From Name',
|
||||
'type' => 'string',
|
||||
'description' => 'The from name of your mail server.',
|
||||
],
|
||||
'mail_mailer' => [
|
||||
'label' => 'Mail Mailer',
|
||||
'type' => 'string',
|
||||
'description' => 'The mailer of your mail server.',
|
||||
],
|
||||
'mail_enabled' => [
|
||||
'label' => 'Mail Enabled',
|
||||
'type' => 'boolean',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class PterodactylSettings extends Settings
|
||||
{
|
||||
public string $admin_token;
|
||||
public string $user_token;
|
||||
public string $panel_url;
|
||||
public int $per_page_limit;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'pterodactyl';
|
||||
}
|
||||
|
||||
public static function encrypted(): array
|
||||
{
|
||||
return [
|
||||
'admin_token',
|
||||
'user_token'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get url with ensured ending backslash
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl(): string
|
||||
{
|
||||
return str_ends_with($this->panel_url, '/') ? $this->panel_url : $this->panel_url . '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of validations array
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function getValidations()
|
||||
{
|
||||
return [
|
||||
'panel_url' => 'required|string|url',
|
||||
'admin_token' => 'required|string',
|
||||
'user_token' => 'required|string',
|
||||
'per_page_limit' => 'required|integer|min:1|max:10000',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of optionTypes
|
||||
* Only used for the settings page
|
||||
* @return array<array<'type'|'label'|'description'|'options', string|bool|float|int|array<string, string>>>
|
||||
*/
|
||||
public static function getOptionInputData()
|
||||
{
|
||||
return [
|
||||
'category_icon' => 'fas fa-server',
|
||||
'panel_url' => [
|
||||
'label' => 'Panel URL',
|
||||
'type' => 'string',
|
||||
'description' => 'The URL to your Pterodactyl panel.',
|
||||
],
|
||||
'admin_token' => [
|
||||
'label' => 'Admin Token',
|
||||
'type' => 'string',
|
||||
'description' => 'The admin user token for your Pterodactyl panel.',
|
||||
],
|
||||
'user_token' => [
|
||||
'label' => 'User Token',
|
||||
'type' => 'string',
|
||||
'description' => 'The user token for your Pterodactyl panel.',
|
||||
],
|
||||
'per_page_limit' => [
|
||||
'label' => 'Per Page Limit',
|
||||
'type' => 'number',
|
||||
'description' => 'The number of servers to show per page.',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class ReferralSettings extends Settings
|
||||
{
|
||||
public string $allowed;
|
||||
public bool $always_give_commission;
|
||||
public bool $enabled;
|
||||
public ?float $reward;
|
||||
public string $mode;
|
||||
public ?int $percentage;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'referral';
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of validations array
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function getValidations()
|
||||
{
|
||||
return [
|
||||
'allowed' => 'required|in:Everyone,Clients',
|
||||
'always_give_commission' => 'nullable|boolean',
|
||||
'enabled' => 'nullable|boolean',
|
||||
'reward' => 'nullable|numeric',
|
||||
'mode' => 'required|in:Commission,Sign-Up,Both',
|
||||
'percentage' => 'nullable|numeric',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of optionTypes
|
||||
* Only used for the settings page
|
||||
* @return array<array<'type'|'label'|'description'|'options', string|bool|float|int|array<string, string>>>
|
||||
*/
|
||||
public static function getOptionInputData()
|
||||
{
|
||||
return [
|
||||
'category_icon' => 'fas fa-user-friends',
|
||||
'allowed' => [
|
||||
'label' => 'Allowed',
|
||||
'type' => 'select',
|
||||
'description' => 'Who is allowed to see their referral-URL',
|
||||
'options' => [
|
||||
'everyone' => 'Everyone',
|
||||
'clients' => 'Clients',
|
||||
],
|
||||
],
|
||||
'always_give_commission' => [
|
||||
'label' => 'Always Give Commission',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Always give commission to the referrer.',
|
||||
],
|
||||
'enabled' => [
|
||||
'label' => 'Enabled',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enable referral system.',
|
||||
],
|
||||
'reward' => [
|
||||
'label' => 'Reward',
|
||||
'type' => 'number',
|
||||
'description' => 'Reward for the referrer.',
|
||||
],
|
||||
'mode' => [
|
||||
'label' => 'Mode',
|
||||
'type' => 'select',
|
||||
'description' => 'Referral mode.',
|
||||
'options' => [
|
||||
'commission' => 'Commission',
|
||||
'sign-up' => 'Sign-Up',
|
||||
'both' => 'Both',
|
||||
],
|
||||
],
|
||||
'percentage' => [
|
||||
'label' => 'Percentage',
|
||||
'type' => 'number',
|
||||
'description' => 'If a referred user buys credits, the referral-user will get x% of the Credits the referred user bought.',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class ServerSettings extends Settings
|
||||
{
|
||||
public int $allocation_limit;
|
||||
public bool $creation_enabled;
|
||||
public bool $enable_upgrade;
|
||||
public bool $charge_first_hour;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'server';
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of validations array
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function getValidations()
|
||||
{
|
||||
return [
|
||||
'allocation_limit' => 'required|integer|min:0',
|
||||
'creation_enabled' => 'nullable|boolean',
|
||||
'enable_upgrade' => 'nullable|boolean',
|
||||
'charge_first_hour' => 'nullable|boolean',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of optionTypes
|
||||
* Only used for the settings page
|
||||
* @return array<array<'type'|'label'|'description'|'options', string|bool|float|int|array<string, string>>>
|
||||
*/
|
||||
public static function getOptionInputData()
|
||||
{
|
||||
return [
|
||||
'category_icon' => 'fas fa-server',
|
||||
'allocation_limit' => [
|
||||
'label' => 'Allocation Limit',
|
||||
'type' => 'number',
|
||||
'description' => 'The maximum amount of allocations to pull per node for automatic deployment, if more allocations are being used than this limit is set to, no new servers can be created.',
|
||||
],
|
||||
'creation_enabled' => [
|
||||
'label' => 'Creation Enabled',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Whether or not users can create servers.',
|
||||
],
|
||||
'enable_upgrade' => [
|
||||
'label' => 'Enable Upgrade',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Whether or not users can upgrade their servers.',
|
||||
],
|
||||
'charge_first_hour' => [
|
||||
'label' => 'Charge First Hour',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Whether or not the first hour of a server is charged.',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class TicketSettings extends Settings
|
||||
{
|
||||
public bool $enabled;
|
||||
public string $notify;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'ticket';
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of validations array
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function getValidations()
|
||||
{
|
||||
return [
|
||||
'enabled' => 'nullable|boolean',
|
||||
'notify' => 'nullable|string',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of optionTypes
|
||||
* Only used for the settings page
|
||||
* @return array<array<'type'|'label'|'description'|'options', string|bool|float|int|array<string, string>>>
|
||||
*/
|
||||
public static function getOptionInputData()
|
||||
{
|
||||
return [
|
||||
'category_icon' => 'fas fa-ticket-alt',
|
||||
'enabled' => [
|
||||
'label' => 'Enabled',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enable or disable the ticket system.',
|
||||
],
|
||||
'notify' => [
|
||||
'label' => 'Notify',
|
||||
'type' => 'select',
|
||||
'description' => 'Who will receive an E-Mail when a new Ticket is created.',
|
||||
'options' => [
|
||||
'admin' => 'Admins',
|
||||
'moderator' => 'Moderators',
|
||||
'all' => 'Admins and Moderators',
|
||||
'none' => 'Nobody',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class UserSettings extends Settings
|
||||
{
|
||||
public float $credits_reward_after_verify_discord;
|
||||
public float $credits_reward_after_verify_email;
|
||||
public bool $force_discord_verification;
|
||||
public bool $force_email_verification;
|
||||
public float $initial_credits;
|
||||
public int $initial_server_limit;
|
||||
public float $min_credits_to_make_server;
|
||||
public int $server_limit_after_irl_purchase;
|
||||
public int $server_limit_after_verify_discord;
|
||||
public int $server_limit_after_verify_email;
|
||||
public bool $register_ip_check;
|
||||
public bool $creation_enabled;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'user';
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of validations array
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function getValidations()
|
||||
{
|
||||
return [
|
||||
'credits_reward_after_verify_discord' => 'required|numeric',
|
||||
'credits_reward_after_verify_email' => 'required|numeric',
|
||||
'force_discord_verification' => 'nullable|boolean',
|
||||
'force_email_verification' => 'nullable|boolean',
|
||||
'initial_credits' => 'required|numeric',
|
||||
'initial_server_limit' => 'required|numeric',
|
||||
'min_credits_to_make_server' => 'required|numeric',
|
||||
'server_limit_after_irl_purchase' => 'required|numeric',
|
||||
'server_limit_after_verify_discord' => 'required|numeric',
|
||||
'server_limit_after_verify_email' => 'required|numeric',
|
||||
'register_ip_check' => 'nullable|boolean',
|
||||
'creation_enabled' => 'nullable|boolean',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of optionTypes
|
||||
* Only used for the settings page
|
||||
* @return array<array<'type'|'label'|'description'|'options', string|boolean|number|array<string, string>>>
|
||||
*/
|
||||
public static function getOptionInputData()
|
||||
{
|
||||
return [
|
||||
'category_icon' => 'fas fa-user',
|
||||
'credits_reward_after_verify_discord' => [
|
||||
'label' => 'Credits Reward After Verify Discord',
|
||||
'type' => 'number',
|
||||
'description' => 'The amount of credits a user gets after verifying their discord account.',
|
||||
],
|
||||
'credits_reward_after_verify_email' => [
|
||||
'label' => 'Credits Reward After Verify Email',
|
||||
'type' => 'number',
|
||||
'description' => 'The amount of credits a user gets after verifying their email.',
|
||||
],
|
||||
'force_discord_verification' => [
|
||||
'label' => 'Force Discord Verification',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Force users to verify their discord account.',
|
||||
],
|
||||
'force_email_verification' => [
|
||||
'label' => 'Force Email Verification',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Force users to verify their email.',
|
||||
],
|
||||
'initial_credits' => [
|
||||
'label' => 'Initial Credits',
|
||||
'type' => 'number',
|
||||
'description' => 'The amount of credits a user gets when they register.',
|
||||
],
|
||||
'initial_server_limit' => [
|
||||
'label' => 'Initial Server Limit',
|
||||
'type' => 'number',
|
||||
'description' => 'The amount of servers a user can create when they register.',
|
||||
],
|
||||
'min_credits_to_make_server' => [
|
||||
'label' => 'Min Credits To Make Server',
|
||||
'type' => 'number',
|
||||
'description' => 'The minimum amount of credits a user needs to create a server.',
|
||||
],
|
||||
'server_limit_after_irl_purchase' => [
|
||||
'label' => 'Server Limit After IRL Purchase',
|
||||
'type' => 'number',
|
||||
'description' => 'The amount of servers a user can create after they purchase a server.',
|
||||
],
|
||||
'server_limit_after_verify_discord' => [
|
||||
'label' => 'Server Limit After Verify Discord',
|
||||
'type' => 'number',
|
||||
'description' => 'The amount of servers a user can create after they verify their discord account.',
|
||||
],
|
||||
'server_limit_after_verify_email' => [
|
||||
'label' => 'Server Limit After Verify Email',
|
||||
'type' => 'number',
|
||||
'description' => 'The amount of servers a user can create after they verify their email.',
|
||||
],
|
||||
'register_ip_check' => [
|
||||
'label' => 'Register IP Check',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Check if the IP a user is registering from is already in use.',
|
||||
],
|
||||
'creation_enabled' => [
|
||||
'label' => 'Creation Enabled',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Whether or not users can create servers.',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class WebsiteSettings extends Settings
|
||||
{
|
||||
|
||||
|
||||
public bool $show_imprint;
|
||||
public bool $show_privacy;
|
||||
public bool $show_tos;
|
||||
public bool $useful_links_enabled;
|
||||
public bool $enable_login_logo;
|
||||
public ?string $seo_title;
|
||||
public ?string $seo_description;
|
||||
public bool $motd_enabled;
|
||||
|
||||
public ?string $motd_message;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'website';
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of validations array
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function getValidations()
|
||||
{
|
||||
return [
|
||||
'motd_enabled' => 'nullable|boolean',
|
||||
'motd_message' => 'nullable|string',
|
||||
'show_imprint' => 'nullable|boolean',
|
||||
'show_privacy' => 'nullable|boolean',
|
||||
'show_tos' => 'nullable|boolean',
|
||||
'useful_links_enabled' => 'nullable|boolean',
|
||||
'enable_login_logo' => 'nullable|boolean',
|
||||
'seo_title' => 'nullable|string',
|
||||
'seo_description' => 'nullable|string',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Summary of optionTypes
|
||||
* Only used for the settings page
|
||||
* @return array<array<'type'|'label'|'description'|'options', string|array<string, string>>>
|
||||
*/
|
||||
public static function getOptionInputData()
|
||||
{
|
||||
return [
|
||||
'category_icon' => 'fas fa-globe',
|
||||
'motd_enabled' => [
|
||||
'label' => 'Enable MOTD',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enable the MOTD (Message of the day) on the dashboard.',
|
||||
],
|
||||
'motd_message' => [
|
||||
'label' => 'MOTD Message',
|
||||
'type' => 'textarea',
|
||||
'description' => 'The message of the day.',
|
||||
],
|
||||
'show_imprint' => [
|
||||
'label' => 'Show Imprint',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Show the imprint on the website.',
|
||||
],
|
||||
'show_privacy' => [
|
||||
'label' => 'Show Privacy',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Show the privacy on the website.',
|
||||
],
|
||||
'show_tos' => [
|
||||
'label' => 'Show TOS',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Show the TOS on the website.',
|
||||
],
|
||||
'useful_links_enabled' => [
|
||||
'label' => 'Enable Useful Links',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enable the useful links on the dashboard.',
|
||||
],
|
||||
'seo_title' => [
|
||||
'label' => 'SEO Title',
|
||||
'type' => 'string',
|
||||
'description' => 'The title of the website.',
|
||||
],
|
||||
'seo_description' => [
|
||||
'label' => 'SEO Description',
|
||||
'type' => 'string',
|
||||
'description' => 'The description of the website.',
|
||||
],
|
||||
'enable_login_logo' => [
|
||||
'label' => 'Enable Login Logo',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enable the logo on the login page.',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -5,34 +5,32 @@ namespace App\Traits;
|
|||
use App\Models\PartnerDiscount;
|
||||
use App\Models\Payment;
|
||||
use App\Models\ShopProduct;
|
||||
use App\Models\Invoice;
|
||||
use App\Notifications\InvoiceNotification;
|
||||
use App\Settings\InvoiceSettings;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use LaravelDaily\Invoices\Classes\Buyer;
|
||||
use LaravelDaily\Invoices\Classes\InvoiceItem;
|
||||
use LaravelDaily\Invoices\Classes\Party;
|
||||
use LaravelDaily\Invoices\Invoice as DailyInvoice;
|
||||
use LaravelDaily\Invoices\Invoice;
|
||||
use Symfony\Component\Intl\Currencies;
|
||||
|
||||
trait Invoiceable
|
||||
{
|
||||
public function createInvoice(Payment $payment, ShopProduct $shopProduct, InvoiceSettings $invoice_settings)
|
||||
public function createInvoice(Payment $payment, ShopProduct $shopProduct)
|
||||
{
|
||||
$user = $payment->user;
|
||||
//create invoice
|
||||
$lastInvoiceID = Invoice::where("invoice_name", "like", "%" . now()->format('mY') . "%")->count("id");
|
||||
$lastInvoiceID = \App\Models\Invoice::where("invoice_name", "like", "%" . now()->format('mY') . "%")->count("id");
|
||||
$newInvoiceID = $lastInvoiceID + 1;
|
||||
$logoPath = storage_path('app/public/logo.png');
|
||||
|
||||
$seller = new Party([
|
||||
'name' => $invoice_settings->company_name,
|
||||
'phone' => $invoice_settings->company_phone,
|
||||
'address' => $invoice_settings->company_address,
|
||||
'vat' => $invoice_settings->company_vat,
|
||||
'name' => config("SETTINGS::INVOICE:COMPANY_NAME"),
|
||||
'phone' => config("SETTINGS::INVOICE:COMPANY_PHONE"),
|
||||
'address' => config("SETTINGS::INVOICE:COMPANY_ADDRESS"),
|
||||
'vat' => config("SETTINGS::INVOICE:COMPANY_VAT"),
|
||||
'custom_fields' => [
|
||||
'E-Mail' => $invoice_settings->company_mail,
|
||||
"Web" => $invoice_settings->company_website
|
||||
'E-Mail' => config("SETTINGS::INVOICE:COMPANY_MAIL"),
|
||||
"Web" => config("SETTINGS::INVOICE:COMPANY_WEBSITE")
|
||||
],
|
||||
]);
|
||||
|
||||
|
@ -53,7 +51,7 @@ trait Invoiceable
|
|||
$notes = implode("<br>", $notes);
|
||||
|
||||
|
||||
$invoice = DailyInvoice::make()
|
||||
$invoice = Invoice::make()
|
||||
->template('controlpanel')
|
||||
->name(__("Invoice"))
|
||||
->buyer($customer)
|
||||
|
@ -66,7 +64,7 @@ trait Invoiceable
|
|||
->series(now()->format('mY'))
|
||||
->delimiter("-")
|
||||
->sequence($newInvoiceID)
|
||||
->serialNumberFormat($invoice_settings->prefix . '{DELIMITER}{SERIES}{SEQUENCE}')
|
||||
->serialNumberFormat(config("SETTINGS::INVOICE:PREFIX") . '{DELIMITER}{SERIES}{SEQUENCE}')
|
||||
->currencyCode(strtoupper($payment->currency_code))
|
||||
->currencySymbol(Currencies::getSymbol(strtoupper($payment->currency_code)))
|
||||
->notes($notes);
|
||||
|
@ -80,7 +78,7 @@ trait Invoiceable
|
|||
$invoice->render();
|
||||
Storage::disk("local")->put("invoice/" . $user->id . "/" . now()->format('Y') . "/" . $invoice->filename, $invoice->output);
|
||||
|
||||
Invoice::create([
|
||||
\App\Models\Invoice::create([
|
||||
'invoice_user' => $user->id,
|
||||
'invoice_name' => $invoice->getSerialNumber(),
|
||||
'payment_id' => $payment->payment_id,
|
||||
|
|
|
@ -11,38 +11,36 @@
|
|||
"php": "^8.1",
|
||||
"ext-intl": "*",
|
||||
"biscolab/laravel-recaptcha": "^5.4",
|
||||
"doctrine/dbal": "^3.5.3",
|
||||
"guzzlehttp/guzzle": "^7.5",
|
||||
"hidehalo/nanoid-php": "^1.1.12",
|
||||
"doctrine/dbal": "^3.1",
|
||||
"guzzlehttp/guzzle": "^7.2",
|
||||
"hidehalo/nanoid-php": "^1.1",
|
||||
"kkomelin/laravel-translatable-string-exporter": "^1.18",
|
||||
"laravel/framework": "^9.50.2",
|
||||
"laravel/tinker": "^2.8",
|
||||
"laravel/ui": "^3.4.6",
|
||||
"laraveldaily/laravel-invoices": "^3.0.2",
|
||||
"league/flysystem-aws-s3-v3": "^3.12.2",
|
||||
"paypal/paypal-checkout-sdk": "^1.0.2",
|
||||
"paypal/rest-api-sdk-php": "^1.14.0",
|
||||
"predis/predis": "*",
|
||||
"qirolab/laravel-themer": "^2.0.2",
|
||||
"socialiteproviders/discord": "^4.1.2",
|
||||
"spatie/laravel-activitylog": "^4.7.3",
|
||||
"spatie/laravel-query-builder": "^5.1.2",
|
||||
"spatie/laravel-settings": "^2.7",
|
||||
"spatie/laravel-validation-rules": "^3.2.2",
|
||||
"stripe/stripe-php": "^7.128",
|
||||
"symfony/http-client": "^6.2.6",
|
||||
"symfony/intl": "^6.2.5",
|
||||
"symfony/mailgun-mailer": "^6.2.5",
|
||||
"yajra/laravel-datatables-oracle": "^9.21.2"
|
||||
"laravel/framework": "^9.46",
|
||||
"laravel/tinker": "^2.7",
|
||||
"laravel/ui": "^3.3",
|
||||
"laraveldaily/laravel-invoices": "^3.0",
|
||||
"league/flysystem-aws-s3-v3": "^3.0",
|
||||
"paypal/paypal-checkout-sdk": "^1.0",
|
||||
"paypal/rest-api-sdk-php": "^1.14",
|
||||
"qirolab/laravel-themer": "^2.0",
|
||||
"socialiteproviders/discord": "^4.1",
|
||||
"spatie/laravel-activitylog": "^4.4",
|
||||
"spatie/laravel-query-builder": "^5.0",
|
||||
"spatie/laravel-validation-rules": "^3.2",
|
||||
"stripe/stripe-php": "^7.107",
|
||||
"symfony/http-client": "^6.2",
|
||||
"symfony/intl": "^6.0",
|
||||
"symfony/mailgun-mailer": "^6.2",
|
||||
"yajra/laravel-datatables-oracle": "^9.19"
|
||||
},
|
||||
"require-dev": {
|
||||
"barryvdh/laravel-debugbar": "^3.7",
|
||||
"fakerphp/faker": "^1.21",
|
||||
"laravel/sail": "^1.19",
|
||||
"mockery/mockery": "^1.5.1",
|
||||
"nunomaduro/collision": "^6.4",
|
||||
"phpunit/phpunit": "^9.6",
|
||||
"spatie/laravel-ignition": "^1.6"
|
||||
"barryvdh/laravel-debugbar": "^3.6",
|
||||
"fakerphp/faker": "^1.9.1",
|
||||
"laravel/sail": "^1.15",
|
||||
"mockery/mockery": "^1.4.4",
|
||||
"nunomaduro/collision": "^6.3",
|
||||
"phpunit/phpunit": "^9.5.10",
|
||||
"spatie/laravel-ignition": "^1.4"
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
|
|
1493
composer.lock
generated
1493
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -210,8 +210,9 @@ return [
|
|||
App\Providers\EventServiceProvider::class,
|
||||
App\Providers\RouteServiceProvider::class,
|
||||
Yajra\DataTables\DataTablesServiceProvider::class,
|
||||
|
||||
KKomelin\TranslatableStringExporter\Providers\ExporterServiceProvider::class,
|
||||
Biscolab\ReCaptcha\ReCaptchaServiceProvider::class,
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|
|
|
@ -93,7 +93,7 @@ return [
|
|||
|
||||
'from' => [
|
||||
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
|
||||
'name' => env('MAIL_FROM_NAME', 'ControlPanel'),
|
||||
'name' => env('MAIL_FROM_NAME', 'Example'),
|
||||
],
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
<?php
|
||||
|
||||
use App\Helpers\ExtensionHelper;
|
||||
use App\Settings\GeneralSettings;
|
||||
use App\Settings\DiscordSettings;
|
||||
use App\Settings\InvoiceSettings;
|
||||
use App\Settings\LocaleSettings;
|
||||
use App\Settings\MailSettings;
|
||||
use App\Settings\PterodactylSettings;
|
||||
use App\Settings\ReferralSettings;
|
||||
use App\Settings\ServerSettings;
|
||||
use App\Settings\UserSettings;
|
||||
use App\Settings\WebsiteSettings;
|
||||
use App\Settings\TicketSettings;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
* Each settings class used in your application must be registered, you can
|
||||
* put them (manually) here.
|
||||
*/
|
||||
'settings' => [
|
||||
GeneralSettings::class,
|
||||
DiscordSettings::class,
|
||||
InvoiceSettings::class,
|
||||
LocaleSettings::class,
|
||||
MailSettings::class,
|
||||
PterodactylSettings::class,
|
||||
ReferralSettings::class,
|
||||
ServerSettings::class,
|
||||
UserSettings::class,
|
||||
WebsiteSettings::class,
|
||||
TicketSettings::class,
|
||||
],
|
||||
|
||||
/*
|
||||
* The path where the settings classes will be created.
|
||||
*/
|
||||
'setting_class_path' => app_path('Settings'),
|
||||
|
||||
/*
|
||||
* In these directories settings migrations will be stored and ran when migrating. A settings
|
||||
* migration created via the make:settings-migration command will be stored in the first path or
|
||||
* a custom defined path when running the command.
|
||||
*/
|
||||
'migrations_paths' => [
|
||||
database_path('settings'),
|
||||
...ExtensionHelper::getAllExtensionMigrations()
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
* When no repository was set for a settings class the following repository
|
||||
* will be used for loading and saving settings.
|
||||
*/
|
||||
'default_repository' => 'database',
|
||||
|
||||
/*
|
||||
* Settings will be stored and loaded from these repositories.
|
||||
*/
|
||||
'repositories' => [
|
||||
'database' => [
|
||||
'type' => Spatie\LaravelSettings\SettingsRepositories\DatabaseSettingsRepository::class,
|
||||
'model' => null,
|
||||
'table' => null,
|
||||
'connection' => null,
|
||||
],
|
||||
'redis' => [
|
||||
'type' => Spatie\LaravelSettings\SettingsRepositories\RedisSettingsRepository::class,
|
||||
'connection' => null,
|
||||
'prefix' => null,
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
* The contents of settings classes can be cached through your application,
|
||||
* settings will be stored within a provided Laravel store and can have an
|
||||
* additional prefix.
|
||||
*/
|
||||
'cache' => [
|
||||
'enabled' => env('SETTINGS_CACHE_ENABLED', true),
|
||||
'store' => 'redis',
|
||||
'prefix' => 'setting',
|
||||
'ttl' => null,
|
||||
],
|
||||
|
||||
/*
|
||||
* These global casts will be automatically used whenever a property within
|
||||
* your settings class isn't a default PHP type.
|
||||
*/
|
||||
'global_casts' => [
|
||||
DateTimeInterface::class => Spatie\LaravelSettings\SettingsCasts\DateTimeInterfaceCast::class,
|
||||
DateTimeZone::class => Spatie\LaravelSettings\SettingsCasts\DateTimeZoneCast::class,
|
||||
// Spatie\DataTransferObject\DataTransferObject::class => Spatie\LaravelSettings\SettingsCasts\DtoCast::class,
|
||||
Spatie\LaravelData\Data::class => Spatie\LaravelSettings\SettingsCasts\DataCast::class,
|
||||
],
|
||||
|
||||
/*
|
||||
* The package will look for settings in these paths and automatically
|
||||
* register them.
|
||||
*/
|
||||
'auto_discover_settings' => [
|
||||
app()->path(),
|
||||
],
|
||||
|
||||
/*
|
||||
* Automatically discovered settings classes can be cached so they don't
|
||||
* need to be searched each time the application boots up.
|
||||
*/
|
||||
'discovered_settings_cache_path' => storage_path('app/laravel-settings'),
|
||||
];
|
|
@ -1,45 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
// rename old settings table
|
||||
Schema::table('settings', function (Blueprint $table) {
|
||||
$table->rename('settings_old');
|
||||
});
|
||||
|
||||
// create new settings table
|
||||
Schema::create('settings', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->json('payload')->nullable();
|
||||
$table->string('group')->index();
|
||||
$table->boolean('locked');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('settings');
|
||||
|
||||
Schema::table('settings_old', function (Blueprint $table) {
|
||||
$table->rename("settings");
|
||||
});
|
||||
}
|
||||
};
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::dropIfExists('settings_old');
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::create('settings_old', function (Blueprint $table) {
|
||||
$table->string('key', 191)->primary();
|
||||
$table->text('value')->nullable();
|
||||
$table->string('type');
|
||||
$table->longText('description')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
};
|
|
@ -1,32 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->string('pterodactyl_id')->change();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->integer('pterodactyl_id')->nullable->change();
|
||||
});
|
||||
}
|
||||
};
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Database\Seeders\Seeds\SettingsSeeder;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class DatabaseSeeder extends Seeder
|
||||
{
|
||||
|
@ -14,6 +14,8 @@ class DatabaseSeeder extends Seeder
|
|||
*/
|
||||
public function run()
|
||||
{
|
||||
// Schema::dropIfExists('settings_old');
|
||||
$this->call([
|
||||
SettingsSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
656
database/seeders/Seeds/SettingsSeeder.php
Normal file
656
database/seeders/Seeds/SettingsSeeder.php
Normal file
|
@ -0,0 +1,656 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders\Seeds;
|
||||
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class SettingsSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
//initials
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::USER:INITIAL_CREDITS',
|
||||
], [
|
||||
'value' => '250',
|
||||
'type' => 'integer',
|
||||
'description' => 'The initial amount of credits the user starts with.',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::USER:INITIAL_SERVER_LIMIT',
|
||||
], [
|
||||
'value' => '1',
|
||||
'type' => 'integer',
|
||||
'description' => 'The initial server limit the user starts with.',
|
||||
]);
|
||||
|
||||
//verify email event
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL',
|
||||
], [
|
||||
'value' => '250',
|
||||
'type' => 'integer',
|
||||
'description' => 'Increase in credits after the user has verified their email account.',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL',
|
||||
], [
|
||||
'value' => '2',
|
||||
'type' => 'integer',
|
||||
'description' => 'Increase in server limit after the user has verified their email account.',
|
||||
]);
|
||||
|
||||
//verify discord event
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD',
|
||||
], [
|
||||
'value' => '375',
|
||||
'type' => 'integer',
|
||||
'description' => 'Increase in credits after the user has verified their discord account.',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD',
|
||||
], [
|
||||
'value' => '2',
|
||||
'type' => 'integer',
|
||||
'description' => 'Increase in server limit after the user has verified their discord account.',
|
||||
]);
|
||||
|
||||
//other
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER',
|
||||
], [
|
||||
'value' => '50',
|
||||
'type' => 'integer',
|
||||
'description' => 'The minimum amount of credits the user would need to make a server.',
|
||||
]);
|
||||
|
||||
//purchasing
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE',
|
||||
], [
|
||||
'value' => '10',
|
||||
'type' => 'integer',
|
||||
'description' => 'updates the users server limit to this amount (unless the user already has a higher server limit) after making a purchase with real money, set to 0 to ignore this.',
|
||||
]);
|
||||
|
||||
//force email and discord verification
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::USER:FORCE_EMAIL_VERIFICATION',
|
||||
], [
|
||||
'value' => 'false',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Force an user to verify the email adress before creating a server / buying credits.',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::USER:FORCE_DISCORD_VERIFICATION',
|
||||
], [
|
||||
'value' => 'false',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Force an user to link an Discord Account before creating a server / buying credits.',
|
||||
]);
|
||||
|
||||
//disable ip check on register
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:REGISTER_IP_CHECK',
|
||||
], [
|
||||
'value' => 'true',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Prevent users from making multiple accounts using the same IP address',
|
||||
]);
|
||||
|
||||
//per_page on allocations request
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SERVER:ALLOCATION_LIMIT',
|
||||
], [
|
||||
'value' => '200',
|
||||
'type' => 'integer',
|
||||
'description' => 'The maximum amount of allocations to pull per node for automatic deployment, if more allocations are being used than this limit is set to, no new servers can be created!',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER',
|
||||
], [
|
||||
'value' => '0',
|
||||
'type' => 'integer',
|
||||
'description' => 'The minimum amount of credits user has to have to create a server. Can be overridden by package limits.'
|
||||
]);
|
||||
|
||||
//credits display name
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME',
|
||||
], [
|
||||
'value' => 'Credits',
|
||||
'type' => 'string',
|
||||
'description' => 'The display name of your currency.',
|
||||
]);
|
||||
|
||||
//credits display name
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR',
|
||||
], [
|
||||
'value' => 'true',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Charges the first hour worth of credits upon creating a server.',
|
||||
]);
|
||||
//sales tax
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::PAYMENTS:SALES_TAX',
|
||||
], [
|
||||
'value' => '0',
|
||||
'type' => 'integer',
|
||||
'description' => 'The %-value of tax that will be added to the product price on checkout.',
|
||||
]);
|
||||
//Invoices enabled
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::INVOICE:ENABLED',
|
||||
], [
|
||||
'value' => 'false',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enables or disables the invoice feature for payments.',
|
||||
]);
|
||||
//Invoice company name
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::INVOICE:COMPANY_NAME',
|
||||
], [
|
||||
'value' => '',
|
||||
'type' => 'string',
|
||||
'description' => 'The name of the Company on the Invoices.',
|
||||
]);
|
||||
//Invoice company address
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::INVOICE:COMPANY_ADDRESS',
|
||||
], [
|
||||
'value' => '',
|
||||
'type' => 'string',
|
||||
'description' => 'The address of the Company on the Invoices.',
|
||||
]);
|
||||
//Invoice company phone
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::INVOICE:COMPANY_PHONE',
|
||||
], [
|
||||
'value' => '',
|
||||
'type' => 'string',
|
||||
'description' => 'The phone number of the Company on the Invoices.',
|
||||
]);
|
||||
|
||||
//Invoice company mail
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::INVOICE:COMPANY_MAIL',
|
||||
], [
|
||||
'value' => '',
|
||||
'type' => 'string',
|
||||
'description' => 'The email address of the Company on the Invoices.',
|
||||
]);
|
||||
|
||||
//Invoice VAT
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::INVOICE:COMPANY_VAT',
|
||||
], [
|
||||
'value' => '',
|
||||
'type' => 'string',
|
||||
'description' => 'The VAT-Number of the Company on the Invoices.',
|
||||
]);
|
||||
|
||||
//Invoice Website
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::INVOICE:COMPANY_WEBSITE',
|
||||
], [
|
||||
'value' => '',
|
||||
'type' => 'string',
|
||||
'description' => 'The Website of the Company on the Invoices.',
|
||||
]);
|
||||
|
||||
//Invoice Website
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::INVOICE:PREFIX',
|
||||
], [
|
||||
'value' => 'INV',
|
||||
'type' => 'string',
|
||||
'description' => 'The invoice prefix.',
|
||||
]);
|
||||
|
||||
//Locale
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::LOCALE:DEFAULT',
|
||||
], [
|
||||
'value' => 'en',
|
||||
'type' => 'string',
|
||||
'description' => 'The default dashboard language.',
|
||||
]);
|
||||
//Dynamic locale
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::LOCALE:DYNAMIC',
|
||||
], [
|
||||
'value' => 'false',
|
||||
'type' => 'boolean',
|
||||
'description' => 'If this is true, the Language will change to the Clients browserlanguage or default.',
|
||||
]);
|
||||
//User can change Locale
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::LOCALE:CLIENTS_CAN_CHANGE',
|
||||
], [
|
||||
'value' => 'false',
|
||||
'type' => 'boolean',
|
||||
'description' => 'If this is true, the clients will be able to change their Locale.',
|
||||
]);
|
||||
//Locale
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::LOCALE:AVAILABLE',
|
||||
], [
|
||||
'value' => 'en',
|
||||
'type' => 'string',
|
||||
'description' => 'The available languages.',
|
||||
]);
|
||||
//Locale
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::LOCALE:DATATABLES',
|
||||
], [
|
||||
'value' => 'en-gb',
|
||||
'type' => 'string',
|
||||
'description' => 'The Language of the Datatables. Grab the Language-Codes from here https://datatables.net/plug-ins/i18n/',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::PAYMENTS:PAYPAL:SECRET',
|
||||
], [
|
||||
'value' => env('PAYPAL_SECRET', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'Your PayPal Secret-Key (https://developer.paypal.com/docs/integration/direct/rest/).',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID',
|
||||
], [
|
||||
'value' => env('PAYPAL_CLIENT_ID', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'Your PayPal Client_ID.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET',
|
||||
], [
|
||||
'value' => env('PAYPAL_SANDBOX_SECRET', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'Your PayPal SANDBOX Secret-Key used for testing.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID',
|
||||
], [
|
||||
'value' => env('PAYPAL_SANDBOX_CLIENT_ID', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'Your PayPal SANDBOX Client-ID used for testing.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::PAYMENTS:STRIPE:SECRET',
|
||||
], [
|
||||
'value' => env('STRIPE_SECRET', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'Your Stripe Secret-Key (https://dashboard.stripe.com/account/apikeys).',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET',
|
||||
], [
|
||||
'value' => env('STRIPE_ENDPOINT_SECRET', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'Your Stripe endpoint secret-key.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::PAYMENTS:STRIPE:TEST_SECRET',
|
||||
], [
|
||||
'value' => env('STRIPE_TEST_SECRET', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'Your Stripe test secret-key.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET',
|
||||
], [
|
||||
'value' => env('STRIPE_ENDPOINT_TEST_SECRET', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'Your Stripe endpoint test secret-key.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::PAYMENTS:STRIPE:METHODS',
|
||||
], [
|
||||
'value' => env('STRIPE_METHODS', 'card,sepa_debit'),
|
||||
'type' => 'string',
|
||||
'description' => 'Comma seperated list of payment methods that are enabled (https://stripe.com/docs/payments/payment-methods/integration-options).',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::DISCORD:CLIENT_ID',
|
||||
], [
|
||||
'value' => env('DISCORD_CLIENT_ID', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'Discord API Credentials (https://discordapp.com/developers/applications/).',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::DISCORD:CLIENT_SECRET',
|
||||
], [
|
||||
'value' => env('DISCORD_CLIENT_SECRET', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'Discord API Credentials (https://discordapp.com/developers/applications/).',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::DISCORD:BOT_TOKEN',
|
||||
], [
|
||||
'value' => env('DISCORD_BOT_TOKEN', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'Discord API Credentials (https://discordapp.com/developers/applications/).',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::DISCORD:GUILD_ID',
|
||||
], [
|
||||
'value' => env('DISCORD_GUILD_ID', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'Discord API Credentials (https://discordapp.com/developers/applications/).',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::DISCORD:ROLE_ID',
|
||||
], [
|
||||
'value' => env('DISCORD_ROLE_ID', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'Discord role that will be assigned to users when they register.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::DISCORD:INVITE_URL',
|
||||
], [
|
||||
'value' => env('DISCORD_INVITE_URL', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'The invite URL to your Discord Server.',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:PTERODACTYL:TOKEN',
|
||||
], [
|
||||
'value' => env('PTERODACTYL_TOKEN', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'Admin API Token from Pterodactyl Panel - necessary for the Panel to work. The Key needs all read&write permissions!',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:PTERODACTYL:URL',
|
||||
], [
|
||||
'value' => env('PTERODACTYL_URL', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'The URL to your Pterodactyl Panel. Must not end with a / ',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT',
|
||||
], [
|
||||
'value' => 200,
|
||||
'type' => 'integer',
|
||||
'description' => 'The Pterodactyl API perPage limit. It is necessary to set it higher than your server count.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::MISC:PHPMYADMIN:URL',
|
||||
], [
|
||||
'value' => env('PHPMYADMIN_URL', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'The URL to your PHPMYADMIN Panel. Must not end with a /, remove to remove database button',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::RECAPTCHA:SITE_KEY',
|
||||
], [
|
||||
'value' => env('RECAPTCHA_SITE_KEY', '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI'),
|
||||
'type' => 'string',
|
||||
'description' => 'Google Recaptcha API Credentials (https://www.google.com/recaptcha/admin) - reCaptcha V2 (not v3)',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::RECAPTCHA:SECRET_KEY',
|
||||
], [
|
||||
'value' => env('RECAPTCHA_SECRET_KEY', '6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe'),
|
||||
'type' => 'string',
|
||||
'description' => 'Google Recaptcha API Credentials (https://www.google.com/recaptcha/admin) - reCaptcha V2 (not v3)',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::RECAPTCHA:ENABLED',
|
||||
], [
|
||||
'value' => 'true',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enables or disables the ReCaptcha feature on the registration/login page.',
|
||||
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::MAIL:MAILER',
|
||||
], [
|
||||
'value' => env('MAIL_MAILER', 'smtp'),
|
||||
'type' => 'string',
|
||||
'description' => 'Selected Mailer (smtp, mailgun, sendgrid, mailtrap).',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::MAIL:HOST',
|
||||
], [
|
||||
'value' => env('MAIL_HOST', 'localhost'),
|
||||
'type' => 'string',
|
||||
'description' => 'Mailer Host Address.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::MAIL:PORT',
|
||||
], [
|
||||
'value' => env('MAIL_PORT', '25'),
|
||||
'type' => 'string',
|
||||
'description' => 'Mailer Server Port.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::MAIL:USERNAME',
|
||||
], [
|
||||
'value' => env('MAIL_USERNAME', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'Mailer Username.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::MAIL:PASSWORD',
|
||||
], [
|
||||
'value' => env('MAIL_PASSWORD', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'Mailer Password.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::MAIL:ENCRYPTION',
|
||||
], [
|
||||
'value' => env('MAIL_ENCRYPTION', 'tls'),
|
||||
'type' => 'string',
|
||||
'description' => 'Mailer Encryption (tls, ssl).',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::MAIL:FROM_ADDRESS',
|
||||
], [
|
||||
'value' => env('MAIL_FROM_ADDRESS', ''),
|
||||
'type' => 'string',
|
||||
'description' => 'Mailer From Address.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::MAIL:FROM_NAME',
|
||||
], [
|
||||
'value' => env('APP_NAME', 'Controlpanel'),
|
||||
'type' => 'string',
|
||||
'description' => 'Mailer From Name.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::REFERRAL::ENABLED',
|
||||
], [
|
||||
'value' => 'false',
|
||||
'type' => 'string',
|
||||
'description' => 'Enable or disable the referral system.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION',
|
||||
], [
|
||||
'value' => 'false',
|
||||
'type' => 'string',
|
||||
'description' => 'Whether referrals get percentage commission only on first purchase or on every purchase',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::REFERRAL::REWARD',
|
||||
], [
|
||||
'value' => 100,
|
||||
'type' => 'integer',
|
||||
'description' => 'Credit reward a user should receive when a user registers with his referral code',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::REFERRAL::ALLOWED',
|
||||
], [
|
||||
'value' => 'client',
|
||||
'type' => 'string',
|
||||
'description' => 'Who should be allowed to to use the referral code. all/client',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::REFERRAL:MODE',
|
||||
], [
|
||||
'value' => 'sign-up',
|
||||
'type' => 'string',
|
||||
'description' => 'Whether referrals get Credits on User-Registration or if a User buys credits',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::REFERRAL:PERCENTAGE',
|
||||
], [
|
||||
'value' => 100,
|
||||
'type' => 'integer',
|
||||
'description' => 'The Percentage value a referred user gets.',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN',
|
||||
], [
|
||||
'value' => '',
|
||||
'type' => 'string',
|
||||
'description' => 'The Client API Key of an Pterodactyl Admin Account.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:ENABLE_UPGRADE',
|
||||
], [
|
||||
'value' => 'false',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enables the updgrade/downgrade feature for servers.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:CREATION_OF_NEW_SERVERS',
|
||||
], [
|
||||
'value' => 'true',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enable creation of new servers',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:CREATION_OF_NEW_USERS',
|
||||
], [
|
||||
'value' => 'true',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enable creation of new users',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:SHOW_IMPRINT',
|
||||
], [
|
||||
|
||||
'value' => "false",
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enable imprint in footer.'
|
||||
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:SHOW_PRIVACY',
|
||||
], [
|
||||
|
||||
'value' => "false",
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enable privacy policy in footer.'
|
||||
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:SHOW_TOS',
|
||||
], [
|
||||
'value' => 'false',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enable Terms of Service in footer.',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:ALERT_ENABLED',
|
||||
], [
|
||||
'value' => 'false',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enable Alerts on Homepage.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:ALERT_TYPE',
|
||||
], [
|
||||
'value' => 'dark',
|
||||
'type' => 'text',
|
||||
'description' => 'Changes the Color of the Alert.',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:ALERT_MESSAGE',
|
||||
], [
|
||||
'value' => '',
|
||||
'type' => 'text',
|
||||
'description' => 'Changes the Content the Alert.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:THEME',
|
||||
], [
|
||||
'value' => 'default',
|
||||
'type' => 'text',
|
||||
'description' => 'Current active theme.',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:USEFULLINKS_ENABLED',
|
||||
], [
|
||||
'value' => 'true',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enable Useful Links on Homepage.',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:MOTD_ENABLED',
|
||||
], [
|
||||
'value' => 'true',
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enable MOTD on Homepage.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:MOTD_MESSAGE',
|
||||
], [
|
||||
'value' => '<h1 style="text-align: center;"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://controlpanel.gg/img/controlpanel.png" alt="" width="200" height="200"><span style="font-size: 36pt;">Controlpanel.gg</span></h1>
|
||||
<p><span style="font-size: 18pt;">Thank you for using our Software</span></p>
|
||||
<p><span style="font-size: 18pt;">If you have any questions, make sure to join our <a href="https://discord.com/invite/4Y6HjD2uyU" target="_blank" rel="noopener">Discord</a></span></p>
|
||||
<p><span style="font-size: 10pt;">(you can change this message in the <a href="admin/settings#system">Settings</a> )</span></p>',
|
||||
'type' => 'text',
|
||||
'description' => 'MOTD Message.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:SEO_TITLE',
|
||||
], [
|
||||
'value' => 'Controlpanel.gg',
|
||||
'type' => 'text',
|
||||
'description' => 'The SEO Title.',
|
||||
]);
|
||||
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::SYSTEM:SEO_DESCRIPTION',
|
||||
], [
|
||||
'value' => 'Billing software for Pterodactyl Dashboard!',
|
||||
'type' => 'text',
|
||||
'description' => 'SEO Description.',
|
||||
]);
|
||||
Settings::firstOrCreate([
|
||||
'key' => 'SETTINGS::TICKET:NOTIFY',
|
||||
], [
|
||||
'value' => 'all',
|
||||
'type' => 'text',
|
||||
'description' => 'Who will get a Email Notifcation on new Tickets.',
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CreateGeneralSettings extends SettingsMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$table_exists = DB::table('settings_old')->exists();
|
||||
|
||||
// Get the user-set configuration values from the old table.
|
||||
$this->migrator->add('general.store_enabled', true);
|
||||
$this->migrator->add('general.credits_display_name', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME') : 'Credits');
|
||||
$this->migrator->addEncrypted('general.recaptcha_site_key', $table_exists ? $this->getOldValue("SETTINGS::RECAPTCHA:SITE_KEY") : env('RECAPTCHA_SITE_KEY', '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI'));
|
||||
$this->migrator->addEncrypted('general.recaptcha_secret_key', $table_exists ? $this->getOldValue("SETTINGS::RECAPTCHA:SECRET_KEY") : env('RECAPTCHA_SECRET_KEY', '6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe'));
|
||||
$this->migrator->add('general.recaptcha_enabled', $table_exists ? $this->getOldValue("SETTINGS::RECAPTCHA:ENABLED") : true);
|
||||
$this->migrator->add('general.phpmyadmin_url', $table_exists ? $this->getOldValue("SETTINGS::MISC:PHPMYADMIN:URL") : env('PHPMYADMIN_URL', ''));
|
||||
$this->migrator->add('general.alert_enabled', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:ALERT_ENABLED") : false);
|
||||
$this->migrator->add('general.alert_type', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:ALERT_TYPE") : 'dark');
|
||||
$this->migrator->add('general.alert_message', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:ALERT_MESSAGE") : '');
|
||||
$this->migrator->add('general.theme', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:THEME") : 'default');
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::table('settings_old')->insert([
|
||||
[
|
||||
'key' => 'SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME',
|
||||
'value' => $this->getNewValue('credits_display_name'),
|
||||
'type' => 'string',
|
||||
'description' => 'The name of the credits on the panel.'
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::SYSTEM:ALERT_ENABLED',
|
||||
'value' => $this->getNewValue('alert_enabled'),
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enable the alert at the top of the panel.'
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::SYSTEM:ALERT_TYPE',
|
||||
'value' => $this->getNewValue('alert_type'),
|
||||
'type' => 'string',
|
||||
'description' => 'The type of alert to display.'
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::SYSTEM:ALERT_MESSAGE',
|
||||
'value' => $this->getNewValue('alert_message'),
|
||||
'type' => 'text',
|
||||
'description' => 'The message to display in the alert.'
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::SYSTEM:THEME',
|
||||
'value' => $this->getNewValue('theme'),
|
||||
'type' => 'string',
|
||||
'description' => 'The theme to use for the panel.'
|
||||
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::RECAPTCHA:SITE_KEY',
|
||||
'value' => $this->getNewValue('recaptcha_site_key'),
|
||||
'type' => 'string',
|
||||
'description' => 'The site key for reCAPTCHA.'
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::RECAPTCHA:SECRET_KEY',
|
||||
'value' => $this->getNewValue('recaptcha_secret_key'),
|
||||
'type' => 'string',
|
||||
'description' => 'The secret key for reCAPTCHA.'
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::RECAPTCHA:ENABLED',
|
||||
'value' => $this->getNewValue('recaptcha_enabled'),
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enable reCAPTCHA on the panel.'
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::MISC:PHPMYADMIN:URL',
|
||||
'value' => $this->getNewValue('phpmyadmin_url'),
|
||||
'type' => 'string',
|
||||
'description' => 'The URL to your phpMyAdmin installation.'
|
||||
],
|
||||
]);
|
||||
|
||||
$this->migrator->delete('general.store_enabled');
|
||||
$this->migrator->delete('general.credits_display_name');
|
||||
$this->migrator->delete('general.recaptcha_site_key');
|
||||
$this->migrator->delete('general.recaptcha_secret_key');
|
||||
$this->migrator->delete('general.recaptcha_enabled');
|
||||
$this->migrator->delete('general.phpmyadmin_url');
|
||||
$this->migrator->delete('general.alert_enabled');
|
||||
$this->migrator->delete('general.alert_type');
|
||||
$this->migrator->delete('general.alert_message');
|
||||
$this->migrator->delete('general.theme');
|
||||
}
|
||||
|
||||
public function getNewValue(string $name)
|
||||
{
|
||||
$new_value = DB::table('settings')->where([['group', '=', 'general'], ['name', '=', $name]])->get(['payload'])->first();
|
||||
|
||||
// Some keys returns '""' as a value.
|
||||
if ($new_value->payload === '""') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// remove the quotes from the string
|
||||
if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
|
||||
return substr($new_value->payload, 1, -1);
|
||||
}
|
||||
|
||||
return $new_value->payload;
|
||||
}
|
||||
|
||||
public function getOldValue(string $key)
|
||||
{
|
||||
// Always get the first value of the key.
|
||||
$old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
|
||||
|
||||
// Handle the old values to return without it being a string in all cases.
|
||||
if ($old_value->type === "string" || $old_value->type === "text") {
|
||||
if (is_null($old_value->value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Some values have the type string, but their values are boolean.
|
||||
if ($old_value->value === "false" || $old_value->value === "true") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return $old_value->value;
|
||||
}
|
||||
|
||||
if ($old_value->type === "boolean") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_INT);
|
||||
}
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CreatePterodactylSettings extends SettingsMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$table_exists = DB::table('settings_old')->exists();
|
||||
|
||||
// Get the user-set configuration values from the old table.
|
||||
$this->migrator->addEncrypted('pterodactyl.admin_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:TOKEN') : env('PTERODACTYL_TOKEN', ''));
|
||||
$this->migrator->addEncrypted('pterodactyl.user_token', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN') : '');
|
||||
$this->migrator->add('pterodactyl.panel_url', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:URL') : env('PTERODACTYL_URL', ''));
|
||||
$this->migrator->add('pterodactyl.per_page_limit', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT') : 200);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
|
||||
|
||||
DB::table('settings_old')->insert([
|
||||
[
|
||||
'key' => 'SETTINGS::SYSTEM:PTERODACTYL:TOKEN',
|
||||
'value' => $this->getNewValue('admin_token'),
|
||||
'type' => 'string',
|
||||
'description' => 'The admin token for the Pterodactyl panel.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN',
|
||||
'value' => $this->getNewValue('user_token'),
|
||||
'type' => 'string',
|
||||
'description' => 'The user token for the Pterodactyl panel.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::SYSTEM:PTERODACTYL:URL',
|
||||
'value' => $this->getNewValue('panel_url'),
|
||||
'type' => 'string',
|
||||
'description' => 'The URL for the Pterodactyl panel.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT',
|
||||
'value' => $this->getNewValue('per_page_limit'),
|
||||
'type' => 'integer',
|
||||
'description' => 'The number of servers to show per page.',
|
||||
],
|
||||
]);
|
||||
|
||||
$this->migrator->delete('pterodactyl.admin_token');
|
||||
$this->migrator->delete('pterodactyl.user_token');
|
||||
$this->migrator->delete('pterodactyl.panel_url');
|
||||
$this->migrator->delete('pterodactyl.per_page_limit');
|
||||
}
|
||||
|
||||
public function getNewValue(string $name)
|
||||
{
|
||||
$new_value = DB::table('settings')->where([['group', '=', 'pterodactyl'], ['name', '=', $name]])->get(['payload'])->first();
|
||||
|
||||
// Some keys returns '""' as a value.
|
||||
if ($new_value->payload === '""') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// remove the quotes from the string
|
||||
if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
|
||||
return substr($new_value->payload, 1, -1);
|
||||
}
|
||||
|
||||
return $new_value->payload;
|
||||
}
|
||||
|
||||
public function getOldValue(string $key)
|
||||
{
|
||||
// Always get the first value of the key.
|
||||
$old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
|
||||
|
||||
// Handle the old values to return without it being a string in all cases.
|
||||
if ($old_value->type === "string" || $old_value->type === "text") {
|
||||
if (is_null($old_value->value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Some values have the type string, but their values are boolean.
|
||||
if ($old_value->value === "false" || $old_value->value === "true") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return $old_value->value;
|
||||
}
|
||||
|
||||
if ($old_value->type === "boolean") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_INT);
|
||||
}
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CreateMailSettings extends SettingsMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$table_exists = DB::table('settings_old')->exists();
|
||||
|
||||
// Get the user-set configuration values from the old table.
|
||||
$this->migrator->add('mail.mail_host', $table_exists ? $this->getOldValue('SETTINGS::MAIL:HOST') : env('MAIL_HOST', 'localhost'));
|
||||
$this->migrator->add('mail.mail_port', $table_exists ? $this->getOldValue('SETTINGS::MAIL:PORT') : env('MAIL_PORT', 25));
|
||||
$this->migrator->add('mail.mail_username', $table_exists ? $this->getOldValue('SETTINGS::MAIL:USERNAME') : env('MAIL_USERNAME', ''));
|
||||
$this->migrator->addEncrypted('mail.mail_password', $table_exists ? $this->getOldValue('SETTINGS::MAIL:PASSWORD') : env('MAIL_PASSWORD', ''));
|
||||
$this->migrator->add('mail.mail_encryption', $table_exists ? $this->getOldValue('SETTINGS::MAIL:ENCRYPTION') : env('MAIL_ENCRYPTION', 'tls'));
|
||||
$this->migrator->add('mail.mail_from_address', $table_exists ? $this->getOldValue('SETTINGS::MAIL:FROM_ADDRESS') : env('MAIL_FROM_ADDRESS', 'example@example.com'));
|
||||
$this->migrator->add('mail.mail_from_name', $table_exists ? $this->getOldValue('SETTINGS::MAIL:FROM_NAME') : env('APP_NAME', 'ControlPanel.gg'));
|
||||
$this->migrator->add('mail.mail_mailer', $table_exists ? $this->getOldValue('SETTINGS::MAIL:MAILER') : env('MAIL_MAILER', 'smtp'));
|
||||
$this->migrator->add('mail.mail_enabled', true);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::table('settings_old')->insert([
|
||||
[
|
||||
'key' => 'SETTINGS::MAIL:HOST',
|
||||
'value' => $this->getNewValue('mail_host'),
|
||||
'type' => 'string',
|
||||
'description' => 'The host of the mail server.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::MAIL:PORT',
|
||||
'value' => $this->getNewValue('mail_port'),
|
||||
'type' => 'integer',
|
||||
'description' => 'The port of the mail server.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::MAIL:USERNAME',
|
||||
'value' => $this->getNewValue('mail_username'),
|
||||
'type' => 'string',
|
||||
'description' => 'The username of the mail server.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::MAIL:PASSWORD',
|
||||
'value' => $this->getNewValue('mail_password'),
|
||||
'type' => 'string',
|
||||
'description' => 'The password of the mail server.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::MAIL:ENCRYPTION',
|
||||
'value' => $this->getNewValue('mail_encryption'),
|
||||
'type' => 'string',
|
||||
'description' => 'The encryption of the mail server.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::MAIL:FROM_ADDRESS',
|
||||
'value' => $this->getNewValue('mail_from_address'),
|
||||
'type' => 'string',
|
||||
'description' => 'The from address of the mail server.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::MAIL:FROM_NAME',
|
||||
'value' => $this->getNewValue('mail_from_name'),
|
||||
'type' => 'string',
|
||||
'description' => 'The from name of the mail server.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::MAIL:MAILER',
|
||||
'value' => $this->getNewValue('mail_mailer'),
|
||||
'type' => 'string',
|
||||
'description' => 'The mailer of the mail server.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::MAIL:ENABLED',
|
||||
'value' => $this->getNewValue('mail_enabled'),
|
||||
'type' => 'boolean',
|
||||
'description' => 'The enabled state of the mail server.',
|
||||
],
|
||||
]);
|
||||
|
||||
$this->migrator->delete('mail.mail_host');
|
||||
$this->migrator->delete('mail.mail_port');
|
||||
$this->migrator->delete('mail.mail_username');
|
||||
$this->migrator->delete('mail.mail_password');
|
||||
$this->migrator->delete('mail.mail_encryption');
|
||||
$this->migrator->delete('mail.mail_from_address');
|
||||
$this->migrator->delete('mail.mail_from_name');
|
||||
$this->migrator->delete('mail.mail_mailer');
|
||||
$this->migrator->delete('mail.mail_enabled');
|
||||
}
|
||||
|
||||
|
||||
public function getNewValue(string $name)
|
||||
{
|
||||
$new_value = DB::table('settings')->where([['group', '=', 'mail'], ['name', '=', $name]])->get(['payload'])->first();
|
||||
|
||||
// Some keys returns '""' as a value.
|
||||
if ($new_value->payload === '""') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// remove the quotes from the string
|
||||
if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
|
||||
return substr($new_value->payload, 1, -1);
|
||||
}
|
||||
|
||||
return $new_value->payload;
|
||||
}
|
||||
public function getOldValue(string $key)
|
||||
{
|
||||
// Always get the first value of the key.
|
||||
$old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
|
||||
|
||||
// Handle the old values to return without it being a string in all cases.
|
||||
if ($old_value->type === "string" || $old_value->type === "text") {
|
||||
if (is_null($old_value->value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Some values have the type string, but their values are boolean.
|
||||
if ($old_value->value === "false" || $old_value->value === "true") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return $old_value->value;
|
||||
}
|
||||
|
||||
if ($old_value->type === "boolean") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_INT);
|
||||
}
|
||||
}
|
|
@ -1,163 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CreateUserSettings extends SettingsMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$table_exists = DB::table('settings_old')->exists();
|
||||
|
||||
// Get the user-set configuration values from the old table.
|
||||
$this->migrator->add('user.credits_reward_after_verify_discord', $table_exists ? $this->getOldValue('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD') : 250);
|
||||
$this->migrator->add('user.credits_reward_after_verify_email', $table_exists ? $this->getOldValue('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL') : 250);
|
||||
$this->migrator->add('user.force_discord_verification', $table_exists ? $this->getOldValue('SETTINGS::USER:FORCE_DISCORD_VERIFICATION') : false);
|
||||
$this->migrator->add('user.force_email_verification', $table_exists ? $this->getOldValue('SETTINGS::USER:FORCE_EMAIL_VERIFICATION') : false);
|
||||
$this->migrator->add('user.initial_credits', $table_exists ? $this->getOldValue('SETTINGS::USER:INITIAL_CREDITS') : 250);
|
||||
$this->migrator->add('user.initial_server_limit', $table_exists ? $this->getOldValue('SETTINGS::USER:INITIAL_SERVER_LIMIT') : 1);
|
||||
$this->migrator->add('user.min_credits_to_make_server', $table_exists ? $this->getOldValue('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER') : 50);
|
||||
$this->migrator->add('user.server_limit_after_irl_purchase', $table_exists ? $this->getOldValue('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE') : 10);
|
||||
$this->migrator->add('user.server_limit_after_verify_discord', $table_exists ? $this->getOldValue('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD') : 2);
|
||||
$this->migrator->add('user.server_limit_after_verify_email', $table_exists ? $this->getOldValue('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL') : 2);
|
||||
$this->migrator->add('user.register_ip_check', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:REGISTER_IP_CHECK") : true);
|
||||
$this->migrator->add('user.creation_enabled', $table_exists ? $this->getOldValue("SETTINGS::SYSTEM:CREATION_OF_NEW_USERS") : true);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::table('settings_old')->insert([
|
||||
[
|
||||
'key' => 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD',
|
||||
'value' => $this->getNewValue('credits_reward_after_verify_discord'),
|
||||
'type' => 'integer',
|
||||
'description' => 'The amount of credits that the user will receive after verifying their Discord account.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL',
|
||||
'value' => $this->getNewValue('credits_reward_after_verify_email'),
|
||||
'type' => 'integer',
|
||||
'description' => 'The amount of credits that the user will receive after verifying their email.',
|
||||
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::USER:FORCE_DISCORD_VERIFICATION',
|
||||
'value' => $this->getNewValue('force_discord_verification'),
|
||||
'type' => 'boolean',
|
||||
'description' => 'If the user must verify their Discord account to use the panel.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::USER:FORCE_EMAIL_VERIFICATION',
|
||||
'value' => $this->getNewValue('force_email_verification'),
|
||||
'type' => 'boolean',
|
||||
'description' => 'If the user must verify their email to use the panel.',
|
||||
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::USER:INITIAL_CREDITS',
|
||||
'value' => $this->getNewValue('initial_credits'),
|
||||
'type' => 'integer',
|
||||
'description' => 'The amount of credits that the user will receive when they register.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::USER:INITIAL_SERVER_LIMIT',
|
||||
'value' => $this->getNewValue('initial_server_limit'),
|
||||
'type' => 'integer',
|
||||
'description' => 'The amount of servers that the user will be able to create when they register.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER',
|
||||
'value' => $this->getNewValue('min_credits_to_make_server'),
|
||||
'type' => 'integer',
|
||||
'description' => 'The minimum amount of credits that the user must have to create a server.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE',
|
||||
'value' => $this->getNewValue('server_limit_after_irl_purchase'),
|
||||
'type' => 'integer',
|
||||
'description' => 'The amount of servers that the user will be able to create after making a real purchase.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD',
|
||||
'value' => $this->getNewValue('server_limit_after_verify_discord'),
|
||||
'type' => 'integer',
|
||||
'description' => 'The amount of servers that the user will be able to create after verifying their Discord account.',
|
||||
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL',
|
||||
'value' => $this->getNewValue('server_limit_after_verify_email'),
|
||||
'type' => 'integer',
|
||||
'description' => 'The amount of servers that the user will be able to create after verifying their email.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::SYSTEM:REGISTER_IP_CHECK',
|
||||
'value' => $this->getNewValue('register_ip_check'),
|
||||
'type' => 'boolean',
|
||||
'description' => 'If the user must verify their IP address to register.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::SYSTEM:CREATION_OF_NEW_USERS',
|
||||
'value' => $this->getNewValue('creation_enabled'),
|
||||
'type' => 'boolean',
|
||||
'description' => 'If the user can register.',
|
||||
],
|
||||
]);
|
||||
|
||||
$this->migrator->delete('user.credits_reward_after_verify_discord');
|
||||
$this->migrator->delete('user.credits_reward_after_verify_email');
|
||||
$this->migrator->delete('user.force_discord_verification');
|
||||
$this->migrator->delete('user.force_email_verification');
|
||||
$this->migrator->delete('user.initial_credits');
|
||||
$this->migrator->delete('user.initial_server_limit');
|
||||
$this->migrator->delete('user.min_credits_to_make_server');
|
||||
$this->migrator->delete('user.server_limit_after_irl_purchase');
|
||||
$this->migrator->delete('user.server_limit_after_verify_discord');
|
||||
$this->migrator->delete('user.server_limit_after_verify_email');
|
||||
$this->migrator->delete('user.register_ip_check');
|
||||
$this->migrator->delete('user.creation_enabled');
|
||||
}
|
||||
|
||||
public function getNewValue(string $name)
|
||||
{
|
||||
$new_value = DB::table('settings')->where([['group', '=', 'user'], ['name', '=', $name]])->get(['payload'])->first();
|
||||
|
||||
// Some keys returns '""' as a value.
|
||||
if ($new_value->payload === '""') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// remove the quotes from the string
|
||||
if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
|
||||
return substr($new_value->payload, 1, -1);
|
||||
}
|
||||
|
||||
return $new_value->payload;
|
||||
}
|
||||
|
||||
public function getOldValue(string $key)
|
||||
{
|
||||
// Always get the first value of the key.
|
||||
$old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
|
||||
|
||||
// Handle the old values to return without it being a string in all cases.
|
||||
if ($old_value->type === "string" || $old_value->type === "text") {
|
||||
if (is_null($old_value->value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Some values have the type string, but their values are boolean.
|
||||
if ($old_value->value === "false" || $old_value->value === "true") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return $old_value->value;
|
||||
}
|
||||
|
||||
if ($old_value->type === "boolean") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_INT);
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CreateServerSettings extends SettingsMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$table_exists = DB::table('settings_old')->exists();
|
||||
|
||||
// Get the user-set configuration values from the old table.
|
||||
$this->migrator->add('server.allocation_limit', $table_exists ? $this->getOldValue('SETTINGS::SERVER:ALLOCATION_LIMIT') : 200);
|
||||
$this->migrator->add('server.creation_enabled', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:CREATION_OF_NEW_SERVERS') : true);
|
||||
$this->migrator->add('server.enable_upgrade', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:ENABLE_UPGRADE') : false);
|
||||
$this->migrator->add('server.charge_first_hour', $table_exists ? $this->getOldValue('SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR') : false);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::table('settings_old')->insert([
|
||||
[
|
||||
'key' => 'SETTINGS::SERVER:ALLOCATION_LIMIT',
|
||||
'value' => $this->getNewValue('allocation_limit'),
|
||||
'type' => 'integer',
|
||||
'description' => 'The number of servers to show per page.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::SYSTEM:CREATION_OF_NEW_SERVERS',
|
||||
'value' => $this->getNewValue('creation_enabled'),
|
||||
'type' => 'boolean',
|
||||
'description' => 'Whether or not users can create new servers.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::SYSTEM:ENABLE_UPGRADE',
|
||||
'value' => $this->getNewValue('enable_upgrade'),
|
||||
'type' => 'boolean',
|
||||
'description' => 'Whether or not users can upgrade their servers.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR',
|
||||
'value' => $this->getNewValue('charge_first_hour'),
|
||||
'type' => 'boolean',
|
||||
'description' => 'Whether or not to charge the user for the first hour of their server.',
|
||||
],
|
||||
]);
|
||||
|
||||
$this->migrator->delete('server.allocation_limit');
|
||||
$this->migrator->delete('server.creation_enabled');
|
||||
$this->migrator->delete('server.enable_upgrade');
|
||||
$this->migrator->delete('server.charge_first_hour');
|
||||
}
|
||||
|
||||
public function getNewValue(string $name)
|
||||
{
|
||||
$new_value = DB::table('settings')->where([['group', '=', 'server'], ['name', '=', $name]])->get(['payload'])->first();
|
||||
|
||||
// Some keys returns '""' as a value.
|
||||
if ($new_value->payload === '""') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// remove the quotes from the string
|
||||
if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
|
||||
return substr($new_value->payload, 1, -1);
|
||||
}
|
||||
|
||||
return $new_value->payload;
|
||||
}
|
||||
|
||||
public function getOldValue(string $key)
|
||||
{
|
||||
// Always get the first value of the key.
|
||||
$old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
|
||||
|
||||
// Handle the old values to return without it being a string in all cases.
|
||||
if ($old_value->type === "string" || $old_value->type === "text") {
|
||||
if (is_null($old_value->value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Some values have the type string, but their values are boolean.
|
||||
if ($old_value->value === "false" || $old_value->value === "true") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return $old_value->value;
|
||||
}
|
||||
|
||||
if ($old_value->type === "boolean") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_INT);
|
||||
}
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CreateInvoiceSettings extends SettingsMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$table_exists = DB::table('settings_old')->exists();
|
||||
|
||||
// Get the user-set configuration values from the old table.
|
||||
$this->migrator->add('invoice.company_address', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_ADDRESS') : '');
|
||||
$this->migrator->add('invoice.company_mail', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_MAIL') : '');
|
||||
$this->migrator->add('invoice.company_name', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_NAME') : '');
|
||||
$this->migrator->add('invoice.company_phone', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_PHONE') : '');
|
||||
$this->migrator->add('invoice.company_vat', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_VAT') : '');
|
||||
$this->migrator->add('invoice.company_website', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:COMPANY_WEBSITE') : '');
|
||||
$this->migrator->add('invoice.enabled', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:ENABLED') : true);
|
||||
$this->migrator->add('invoice.prefix', $table_exists ? $this->getOldValue('SETTINGS::INVOICE:PREFIX') : 'INV');
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::table('settings_old')->insert([
|
||||
[
|
||||
'key' => 'SETTINGS::INVOICE:COMPANY_ADDRESS',
|
||||
'value' => $this->getNewValue('company_address'),
|
||||
'type' => 'string',
|
||||
'description' => 'The address of the company.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::INVOICE:COMPANY_MAIL',
|
||||
'value' => $this->getNewValue('company_mail'),
|
||||
'type' => 'string',
|
||||
'description' => 'The email address of the company.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::INVOICE:COMPANY_NAME',
|
||||
'value' => $this->getNewValue('company_name'),
|
||||
'type' => 'string',
|
||||
'description' => 'The name of the company.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::INVOICE:COMPANY_PHONE',
|
||||
'value' => $this->getNewValue('company_phone'),
|
||||
'type' => 'string',
|
||||
'description' => 'The phone number of the company.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::INVOICE:COMPANY_VAT',
|
||||
'value' => $this->getNewValue('company_vat'),
|
||||
'type' => 'string',
|
||||
'description' => 'The VAT number of the company.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::INVOICE:COMPANY_WEBSITE',
|
||||
'value' => $this->getNewValue('company_website'),
|
||||
'type' => 'string',
|
||||
'description' => 'The website of the company.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::INVOICE:ENABLED',
|
||||
'value' => $this->getNewValue('enabled'),
|
||||
'type' => 'boolean',
|
||||
'description' => 'Enable or disable the invoice system.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::INVOICE:PREFIX',
|
||||
'value' => $this->getNewValue('prefix'),
|
||||
'type' => 'string',
|
||||
'description' => 'The prefix of the invoice.',
|
||||
],
|
||||
]);
|
||||
|
||||
$this->migrator->delete('invoice.company_address');
|
||||
$this->migrator->delete('invoice.company_mail');
|
||||
$this->migrator->delete('invoice.company_name');
|
||||
$this->migrator->delete('invoice.company_phone');
|
||||
$this->migrator->delete('invoice.company_vat');
|
||||
$this->migrator->delete('invoice.company_website');
|
||||
$this->migrator->delete('invoice.enabled');
|
||||
$this->migrator->delete('invoice.prefix');
|
||||
}
|
||||
|
||||
public function getNewValue(string $name)
|
||||
{
|
||||
$new_value = DB::table('settings')->where([['group', '=', 'invoice'], ['name', '=', $name]])->get(['payload'])->first();
|
||||
|
||||
// Some keys returns '""' as a value.
|
||||
if ($new_value->payload === '""') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// remove the quotes from the string
|
||||
if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
|
||||
return substr($new_value->payload, 1, -1);
|
||||
}
|
||||
|
||||
return $new_value->payload;
|
||||
}
|
||||
|
||||
public function getOldValue(string $key)
|
||||
{
|
||||
// Always get the first value of the key.
|
||||
$old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
|
||||
|
||||
// Handle the old values to return without it being a string in all cases.
|
||||
if ($old_value->type === "string" || $old_value->type === "text") {
|
||||
if (is_null($old_value->value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Some values have the type string, but their values are boolean.
|
||||
if ($old_value->value === "false" || $old_value->value === "true") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return $old_value->value;
|
||||
}
|
||||
|
||||
if ($old_value->type === "boolean") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_INT);
|
||||
}
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CreateDiscordSettings extends SettingsMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$table_exists = DB::table('settings_old')->exists();
|
||||
|
||||
// Get the user-set configuration values from the old table.
|
||||
$this->migrator->addEncrypted('discord.bot_token', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:BOT_TOKEN') : '');
|
||||
$this->migrator->addEncrypted('discord.client_id', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:CLIENT_ID') : '');
|
||||
$this->migrator->addEncrypted('discord.client_secret', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:CLIENT_SECRET') : '');
|
||||
$this->migrator->add('discord.guild_id', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:GUILD_ID') : '');
|
||||
$this->migrator->add('discord.invite_url', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:INVITE_URL') : '');
|
||||
$this->migrator->add('discord.role_id', $table_exists ? $this->getOldValue('SETTINGS::DISCORD:ROLE_ID') : '');
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::table('settings_old')->insert([
|
||||
[
|
||||
'key' => 'SETTINGS::DISCORD:BOT_TOKEN',
|
||||
'value' => $this->getNewValue('bot_token'),
|
||||
'type' => 'string',
|
||||
'description' => 'The bot token for the Discord bot.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::DISCORD:CLIENT_ID',
|
||||
'value' => $this->getNewValue('client_id'),
|
||||
'type' => 'string',
|
||||
'description' => 'The client ID for the Discord bot.',
|
||||
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::DISCORD:CLIENT_SECRET',
|
||||
'value' => $this->getNewValue('client_secret'),
|
||||
'type' => 'string',
|
||||
'description' => 'The client secret for the Discord bot.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::DISCORD:GUILD_ID',
|
||||
'value' => $this->getNewValue('guild_id'),
|
||||
'type' => 'string',
|
||||
'description' => 'The guild ID for the Discord bot.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::DISCORD:INVITE_URL',
|
||||
'value' => $this->getNewValue('invite_url'),
|
||||
'type' => 'string',
|
||||
'description' => 'The invite URL for the Discord bot.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::DISCORD:ROLE_ID',
|
||||
'value' => $this->getNewValue('role_id'),
|
||||
'type' => 'string',
|
||||
'description' => 'The role ID for the Discord bot.',
|
||||
]
|
||||
]);
|
||||
|
||||
$this->migrator->delete('discord.bot_token');
|
||||
$this->migrator->delete('discord.client_id');
|
||||
$this->migrator->delete('discord.client_secret');
|
||||
$this->migrator->delete('discord.guild_id');
|
||||
$this->migrator->delete('discord.invite_url');
|
||||
$this->migrator->delete('discord.role_id');
|
||||
}
|
||||
|
||||
public function getNewValue(string $name)
|
||||
{
|
||||
$new_value = DB::table('settings')->where([['group', '=', 'discord'], ['name', '=', $name]])->get(['payload'])->first();
|
||||
|
||||
// Some keys returns '""' as a value.
|
||||
if ($new_value->payload === '""') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// remove the quotes from the string
|
||||
if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
|
||||
return substr($new_value->payload, 1, -1);
|
||||
}
|
||||
|
||||
return $new_value->payload;
|
||||
}
|
||||
|
||||
public function getOldValue(string $key)
|
||||
{
|
||||
// Always get the first value of the key.
|
||||
$old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
|
||||
|
||||
// Handle the old values to return without it being a string in all cases.
|
||||
if ($old_value->type === "string" || $old_value->type === "text") {
|
||||
if (is_null($old_value->value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Some values have the type string, but their values are boolean.
|
||||
if ($old_value->value === "false" || $old_value->value === "true") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return $old_value->value;
|
||||
}
|
||||
|
||||
if ($old_value->type === "boolean") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_INT);
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CreateLocaleSettings extends SettingsMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$table_exists = DB::table('settings_old')->exists();
|
||||
|
||||
// Get the user-set configuration values from the old table.
|
||||
$this->migrator->add('locale.available', $table_exists ? $this->getOldValue('SETTINGS::LOCALE:AVAILABLE') : '');
|
||||
$this->migrator->add('locale.clients_can_change', $table_exists ? $this->getOldValue('SETTINGS::LOCALE:CLIENTS_CAN_CHANGE') : true);
|
||||
$this->migrator->add('locale.datatables', $table_exists ? $this->getOldValue('SETTINGS::LOCALE:DATATABLES') : 'en-gb');
|
||||
$this->migrator->add('locale.default', $table_exists ? $this->getOldValue('SETTINGS::LOCALE:DEFAULT') : 'en');
|
||||
$this->migrator->add('locale.dynamic', $table_exists ? $this->getOldValue('SETTINGS::LOCALE:DYNAMIC') : false);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::table('settings_old')->insert([
|
||||
[
|
||||
'key' => 'SETTINGS::LOCALE:AVAILABLE',
|
||||
'value' => $this->getNewValue('available'),
|
||||
'type' => 'string',
|
||||
'description' => 'The available locales.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::LOCALE:CLIENTS_CAN_CHANGE',
|
||||
'value' => $this->getNewValue('clients_can_change'),
|
||||
'type' => 'boolean',
|
||||
'description' => 'If clients can change their locale.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::LOCALE:DATATABLES',
|
||||
'value' => $this->getNewValue('datatables'),
|
||||
'type' => 'string',
|
||||
'description' => 'The locale for datatables.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::LOCALE:DEFAULT',
|
||||
'value' => $this->getNewValue('default'),
|
||||
'type' => 'string',
|
||||
'description' => 'The default locale.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::LOCALE:DYNAMIC',
|
||||
'value' => $this->getNewValue('dynamic'),
|
||||
'type' => 'boolean',
|
||||
'description' => 'If the locale should be dynamic.',
|
||||
],
|
||||
]);
|
||||
|
||||
$this->migrator->delete('locale.available');
|
||||
$this->migrator->delete('locale.clients_can_change');
|
||||
$this->migrator->delete('locale.datatables');
|
||||
$this->migrator->delete('locale.default');
|
||||
$this->migrator->delete('locale.dynamic');
|
||||
}
|
||||
|
||||
public function getNewValue(string $name)
|
||||
{
|
||||
$new_value = DB::table('settings')->where([['group', '=', 'locale'], ['name', '=', $name]])->get(['payload'])->first();
|
||||
|
||||
// Some keys returns '""' as a value.
|
||||
if ($new_value->payload === '""') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// remove the quotes from the string
|
||||
if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
|
||||
return substr($new_value->payload, 1, -1);
|
||||
}
|
||||
|
||||
return $new_value->payload;
|
||||
}
|
||||
|
||||
public function getOldValue(string $key)
|
||||
{
|
||||
// Always get the first value of the key.
|
||||
$old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
|
||||
|
||||
// Handle the old values to return without it being a string in all cases.
|
||||
if ($old_value->type === "string" || $old_value->type === "text") {
|
||||
if (is_null($old_value->value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Some values have the type string, but their values are boolean.
|
||||
if ($old_value->value === "false" || $old_value->value === "true") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return $old_value->value;
|
||||
}
|
||||
|
||||
if ($old_value->type === "boolean") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_INT);
|
||||
}
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CreateReferralSettings extends SettingsMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$table_exists = DB::table('settings_old')->exists();
|
||||
|
||||
// Get the user-set configuration values from the old table.
|
||||
$this->migrator->add('referral.allowed', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL::ALLOWED') : 'client');
|
||||
$this->migrator->add('referral.always_give_commission', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION') : false);
|
||||
$this->migrator->add('referral.enabled', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL::ENABLED') : false);
|
||||
$this->migrator->add('referral.reward', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL::REWARD') : 100);
|
||||
$this->migrator->add('referral.mode', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL:MODE') : 'sign-up');
|
||||
$this->migrator->add('referral.percentage', $table_exists ? $this->getOldValue('SETTINGS::REFERRAL:PERCENTAGE') : 100);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::table('settings_old')->insert([
|
||||
[
|
||||
'key' => 'SETTINGS::REFERRAL::ALLOWED',
|
||||
'value' => $this->getNewValue('allowed'),
|
||||
'type' => 'string',
|
||||
'description' => 'The allowed referral types.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION',
|
||||
'value' => $this->getNewValue('always_give_commission'),
|
||||
'type' => 'boolean',
|
||||
'description' => 'Whether to always give commission to the referrer.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::REFERRAL::ENABLED',
|
||||
'value' => $this->getNewValue('enabled'),
|
||||
'type' => 'boolean',
|
||||
'description' => 'Whether to enable the referral system.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::REFERRAL::REWARD',
|
||||
'value' => $this->getNewValue('reward'),
|
||||
'type' => 'integer',
|
||||
'description' => 'The reward for the referral.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::REFERRAL:MODE',
|
||||
'value' => $this->getNewValue('mode'),
|
||||
'type' => 'string',
|
||||
'description' => 'The referral mode.',
|
||||
],
|
||||
[
|
||||
'key' => 'SETTINGS::REFERRAL:PERCENTAGE',
|
||||
'value' => $this->getNewValue('percentage'),
|
||||
'type' => 'integer',
|
||||
'description' => 'The referral percentage.',
|
||||
],
|
||||
]);
|
||||
|
||||
$this->migrator->delete('referral.allowed');
|
||||
$this->migrator->delete('referral.always_give_commission');
|
||||
$this->migrator->delete('referral.enabled');
|
||||
$this->migrator->delete('referral.reward');
|
||||
$this->migrator->delete('referral.mode');
|
||||
$this->migrator->delete('referral.percentage');
|
||||
}
|
||||
|
||||
public function getNewValue(string $name)
|
||||
{
|
||||
$new_value = DB::table('settings')->where([['group', '=', 'referral'], ['name', '=', $name]])->get(['payload'])->first();
|
||||
|
||||
// Some keys returns '""' as a value.
|
||||
if ($new_value->payload === '""') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// remove the quotes from the string
|
||||
if (substr($new_value->payload, 0, 1) === '"' && substr($new_value->payload, -1) === '"') {
|
||||
return substr($new_value->payload, 1, -1);
|
||||
}
|
||||
|
||||
return $new_value->payload;
|
||||
}
|
||||
|
||||
public function getOldValue(string $key)
|
||||
{
|
||||
// Always get the first value of the key.
|
||||
$old_value = DB::table('settings_old')->where('key', '=', $key)->get(['value', 'type'])->first();
|
||||
|
||||
// Handle the old values to return without it being a string in all cases.
|
||||
if ($old_value->type === "string" || $old_value->type === "text") {
|
||||
if (is_null($old_value->value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Some values have the type string, but their values are boolean.
|
||||
if ($old_value->value === "false" || $old_value->value === "true") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return $old_value->value;
|
||||
}
|
||||
|
||||
if ($old_value->type === "boolean") {
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_BOOL);
|
||||
}
|
||||
|
||||
return filter_var($old_value->value, FILTER_VALIDATE_INT);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue