├── plugins └── .gitkeep ├── migrations ├── .gitignore ├── Version20250204125527.php ├── Version20251109014447.php ├── Version20250128174115.php ├── Version20251011101804.php ├── Version20250126190537.php ├── Version20240124203658.php ├── Version20250913222644.php ├── Version20251027130000.php ├── Version20241126171453.php ├── Version20250311193917.php ├── Version20241127122406.php ├── Version20241227012239.php ├── Version20240129135319.php ├── Version20251215100714.php ├── Version20250106174956.php ├── Version20250127091507.php ├── Version20251207161731.php ├── Version20250708142015.php ├── Version20250309181442.php ├── Version20251220010323.php ├── Version20240909174033.php ├── Version20240812195530.php ├── Version20240825133509.php ├── Version20250708170843.php ├── Version20240730183226.php ├── Version20240808175110.php ├── Version20250705224050.php ├── Version20240803231552.php ├── Version20240804130207.php ├── Version20240804133717.php ├── Version20240804192020.php ├── Version20240730175747.php ├── Version20240730180609.php ├── Version20240730194105.php ├── Version20240803231415.php ├── Version20240803235341.php ├── Version20240904184555.php ├── Version20240825110754.php ├── Version20240805105949.php └── Version20251215175124.php ├── public ├── plugins │ └── .gitkeep ├── uploads │ ├── avatars │ │ └── .gitkeep │ ├── products │ │ └── .gitkeep │ ├── settings │ │ └── .gitkeep │ └── categories │ │ └── .gitkeep └── assets │ ├── img │ ├── logo │ │ └── logo.png │ ├── favicon │ │ ├── favicon.ico │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── apple-touch-icon.png │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ └── site.webmanifest │ └── placeholders │ │ └── 300x150.png │ └── theme │ └── default │ └── fonts │ ├── Inter-Bold.woff2 │ ├── Poppins-Bold.ttf │ ├── Inter-Medium.woff2 │ ├── Inter-Regular.woff2 │ ├── Inter-SemiBold.woff2 │ └── Poppins-SemiBold.ttf ├── src └── Core │ ├── Entity │ ├── .gitignore │ ├── Payment.php │ ├── Panel │ │ └── UserPayment.php │ └── ProductPrice.php │ ├── Controller │ ├── .gitignore │ ├── API │ │ ├── Admin │ │ │ ├── AbstractAdminAPIController.php │ │ │ ├── VersionController.php │ │ │ └── TemplateController.php │ │ ├── APIAbstractController.php │ │ └── EggsController.php │ ├── Panel │ │ └── Setting │ │ │ ├── GeneralSettingCrudController.php │ │ │ ├── PaymentSettingCrudController.php │ │ │ ├── SecuritySettingCrudController.php │ │ │ └── PterodactylSettingCrudController.php │ └── DefaultController.php │ ├── Repository │ ├── .gitignore │ ├── ServerProductRepository.php │ ├── ProductRepository.php │ ├── ServerProductPriceRepository.php │ ├── ProductPriceRepository.php │ ├── VoucherRepository.php │ └── LogRepository.php │ ├── Resources │ ├── translations │ │ ├── .gitignore │ │ ├── validators.cn.yaml │ │ ├── validators.id.yaml │ │ ├── validators.hi.yaml │ │ ├── validators.en.yaml │ │ ├── validators.pl.yaml │ │ ├── validators.pt.yaml │ │ ├── validators.nl.yaml │ │ ├── validators.ua.yaml │ │ ├── validators.it.yaml │ │ ├── validators.de.yaml │ │ ├── validators.fr.yaml │ │ ├── validators.ru.yaml │ │ ├── validators.de_CH.yaml │ │ └── validators.es.yaml │ └── config │ │ ├── twig.yaml │ │ ├── translation.yaml │ │ ├── routes.yaml │ │ ├── vich_uploader.yaml │ │ ├── security.yaml │ │ └── monolog.yaml │ ├── Handler │ ├── HandlerInterface.php │ └── MakeThemeHandler.php │ ├── Exception │ ├── Plugin │ │ ├── ZipBombException.php │ │ ├── FileTooLargeException.php │ │ ├── MaliciousZipException.php │ │ ├── InvalidFileTypeException.php │ │ ├── InvalidManifestException.php │ │ ├── InvalidZipFileException.php │ │ ├── MissingManifestException.php │ │ ├── ManifestValidationException.php │ │ ├── InvalidFileExtensionException.php │ │ ├── PluginAlreadyExistsException.php │ │ ├── PluginUploadException.php │ │ └── InvalidStateTransitionException.php │ ├── Pterodactyl │ │ ├── PterodactylServerException.php │ │ ├── PterodactylNotFoundException.php │ │ ├── PterodactylClientApiException.php │ │ ├── PterodactylConnectionException.php │ │ ├── PterodactylRateLimitException.php │ │ ├── PterodactylAccessDeniedException.php │ │ ├── PterodactylApplicationApiException.php │ │ ├── PterodactylAuthenticationException.php │ │ └── PterodactylValidationException.php │ ├── DisabledCommandException.php │ ├── PaymentExpiredException.php │ ├── UserDoesNotHaveClientApiKeyException.php │ ├── PterodactylUserNotFoundException.php │ ├── Email │ │ ├── ServerDetailsNotAvailableException.php │ │ └── ProductPriceNotFoundException.php │ ├── CouldNotCreatePterodactylClientApiKeyException.php │ └── PterodactylAccountEmailAlreadyExists.php │ ├── Enum │ ├── ServerLogSourceTypeEnum.php │ ├── PaymentStatusEnum.php │ ├── CrudFlashMessageTypeEnum.php │ ├── ProductPriceTypeEnum.php │ ├── EmailVerificationValueEnum.php │ ├── ServerStatusEnum.php │ ├── WidgetPosition.php │ ├── ServerStateEnum.php │ ├── ProductHealthStatusEnum.php │ ├── EmailTypeEnum.php │ ├── ProductPriceUnitEnum.php │ ├── LanguageEnum.php │ ├── VoucherTypeEnum.php │ ├── CrudTemplateContextEnum.php │ ├── OverwriteableCrudTemplatesEnum.php │ ├── SettingContextEnum.php │ ├── WidgetContext.php │ ├── SettingTypeEnum.php │ ├── LogActionEnum.php │ ├── ServerLogActionEnum.php │ └── ViewNameEnum.php │ ├── Contract │ ├── Pterodactyl │ │ ├── MetaAccessInterface.php │ │ ├── Application │ │ │ ├── PterodactylPterocaInterface.php │ │ │ └── PterodactylNestsInterface.php │ │ └── Client │ │ │ ├── PterodactylDatabasesInterface.php │ │ │ ├── PterodactylNetworkInterface.php │ │ │ ├── PterodactylClientAdapterInterface.php │ │ │ └── PterodactylBackupsInterface.php │ ├── Tab │ │ └── ServerTabInterface.php │ ├── Widget │ │ └── DashboardWidgetInterface.php │ └── ProductPriceInterface.php │ ├── Provider │ └── Captcha │ │ └── CaptchaProviderInterface.php │ ├── Service │ ├── Mailer │ │ └── MailerServiceInterface.php │ ├── System │ │ └── IpAddressProviderService.php │ ├── Email │ │ └── ClientPanelUrlResolverService.php │ ├── Product │ │ └── ProductPriceCalculatorService.php │ ├── Captcha │ │ └── CaptchaService.php │ ├── Pterodactyl │ │ ├── PterodactylExceptionHandler.php │ │ └── PterodactylUsernameService.php │ └── Server │ │ ├── ServerNestService.php │ │ └── ServerConfiguration │ │ └── AbstractServerConfiguration.php │ ├── DTO │ ├── Action │ │ └── Result │ │ │ ├── ConfiguratorVerificationResult.php │ │ │ ├── ServerAllocationActionResult.php │ │ │ ├── RegisterUserActionResult.php │ │ │ └── UpdateServerActionResult.php │ ├── PterodactylAddonVersionDTO.php │ ├── Email │ │ ├── EmailVerificationContextDTO.php │ │ ├── RegistrationEmailContextDTO.php │ │ └── ServerSuspensionContextDTO.php │ ├── Pterodactyl │ │ ├── Credentials.php │ │ ├── Application │ │ │ └── PterodactylApiKey.php │ │ └── Client │ │ │ ├── PterodactylDatabase.php │ │ │ ├── PterodactylFile.php │ │ │ └── PterodactylApiKey.php │ ├── SystemVersionDTO.php │ ├── ServerVariableDTO.php │ ├── TemplateOptionsDTO.php │ ├── ServerLogDTO.php │ ├── PaginationDTO.php │ ├── Collection │ │ └── ServerVariableCollection.php │ ├── ServerWebsocketDTO.php │ ├── PaymentSessionDTO.php │ └── ServerDetailsDTO.php │ ├── Attribute │ └── RequiresVerifiedEmail.php │ ├── Trait │ ├── FormatBytesTrait.php │ ├── ExperimentalFeatureMessageTrait.php │ ├── GetUserTrait.php │ └── CrudFlashMessagesTrait.php │ ├── Tests │ ├── Unit │ │ └── Service │ │ │ └── LocaleServiceTest.php │ └── Integration │ │ └── Controller │ │ └── DefaultControllerTest.php │ ├── Adapter │ └── Pterodactyl │ │ └── AbstractPterodactylAdapter.php │ ├── Event │ ├── Plugin │ │ ├── PluginDisabledEvent.php │ │ ├── PluginEnabledEvent.php │ │ ├── PluginRegisteredEvent.php │ │ ├── PluginFaultedEvent.php │ │ ├── PluginDiscoveredEvent.php │ │ ├── PluginUpdatedEvent.php │ │ └── PluginIndexPageAccessedEvent.php │ ├── Crud │ │ ├── CrudEntityDeletedEvent.php │ │ ├── CrudEntityPersistedEvent.php │ │ ├── CrudEntityUpdatedEvent.php │ │ ├── CrudEntityDeletingEvent.php │ │ ├── CrudEntityUpdatingEvent.php │ │ ├── CrudEntityPersistingEvent.php │ │ ├── CrudConfiguredEvent.php │ │ ├── CrudActionsConfiguredEvent.php │ │ └── CrudFiltersConfiguredEvent.php │ ├── Cli │ │ ├── SynchronizeData │ │ │ └── DataSyncProcessStartedEvent.php │ │ ├── SuspendUnpaidServers │ │ │ └── SuspendUnpaidServersProcessStartedEvent.php │ │ ├── ChangePassword │ │ │ └── PasswordChangeProcessStartedEvent.php │ │ ├── DeleteInactiveServers │ │ │ └── DeleteInactiveServersProcessStartedEvent.php │ │ ├── CreateUser │ │ │ └── UserCreationProcessStartedEvent.php │ │ └── MigrateServers │ │ │ └── ServerMigrationProcessStartedEvent.php │ ├── Server │ │ ├── ServerUnsuspendedEvent.php │ │ ├── ServerProductCreatedEvent.php │ │ ├── ServerRenewalValidatedEvent.php │ │ ├── ServerPurchaseCompletedEvent.php │ │ ├── Tab │ │ │ └── ServerTabsCollectedEvent.php │ │ ├── ServerRenewalCompletedEvent.php │ │ ├── ServersListAccessedEvent.php │ │ ├── ServerEntityCreatedEvent.php │ │ ├── ServerCreatedOnPterodactylEvent.php │ │ ├── ServerEulaAcceptedEvent.php │ │ ├── ServerExpirationExtendedEvent.php │ │ ├── ServerDetailsRequestedEvent.php │ │ ├── Network │ │ │ └── ServerAllocationCreatedEvent.php │ │ ├── ServerWebsocketTokenGeneratedEvent.php │ │ ├── ServerWebsocketTokenRequestedEvent.php │ │ └── ServerPurchaseValidatedEvent.php │ ├── Voucher │ │ ├── VoucherDeletedEvent.php │ │ ├── VoucherUpdateRequestedEvent.php │ │ └── VoucherDeletionRequestedEvent.php │ ├── User │ │ └── Registration │ │ │ ├── UserCreatedEvent.php │ │ │ ├── UserEmailVerifiedEvent.php │ │ │ ├── UserAboutToBeCreatedEvent.php │ │ │ ├── UserRegisteredEvent.php │ │ │ └── UserRegistrationFailedEvent.php │ ├── AbstractDomainEvent.php │ ├── Cart │ │ ├── CartTopUpDataLoadedEvent.php │ │ ├── CartRenewPageAccessedEvent.php │ │ └── CartConfigurePageAccessedEvent.php │ ├── Store │ │ └── StoreAccessedEvent.php │ └── StoppableEventTrait.php │ ├── Form │ ├── ProductPriceSlotFormType.php │ ├── ProductPriceFixedFormType.php │ └── ProductPriceDynamicFormType.php │ ├── Message │ └── SendEmailMessage.php │ ├── MessageHandler │ └── SendEmailMessageHandler.php │ ├── EventSubscriber │ └── User │ │ └── UserRegistrationSubscriber.php │ └── Factory │ └── ServerVariableFactory.php ├── config ├── packages │ ├── vich_uploader.yaml │ ├── mailer.yaml │ ├── property_info.yaml │ ├── translation.yaml │ ├── twig_component.yaml │ ├── doctrine_migrations.yaml │ ├── csrf.yaml │ ├── twig.yaml │ ├── routing.yaml │ ├── validator.yaml │ ├── dev │ │ └── web_profiler.yaml │ ├── framework.yaml │ ├── nyholm_psr7.yaml │ └── cache.yaml ├── routes │ ├── security.yaml │ ├── framework.yaml │ └── dev │ │ └── web_profiler.yaml ├── preload.php └── services.yaml ├── themes └── default │ ├── panel │ ├── crud │ │ ├── user_account │ │ │ └── edit.html.twig │ │ ├── voucher │ │ │ ├── new.html.twig │ │ │ └── edit.html.twig │ │ ├── product │ │ │ ├── new.html.twig │ │ │ └── edit.html.twig │ │ ├── server_product │ │ │ ├── edit.html.twig │ │ │ └── new.html.twig │ │ ├── user_payment │ │ │ └── index.html.twig │ │ └── setting │ │ │ └── current_theme │ │ │ └── edit.html.twig │ ├── servers │ │ └── components │ │ │ └── alert.html.twig │ ├── page │ │ └── default.html.twig │ ├── server │ │ └── tabs │ │ │ └── settings │ │ │ └── settings.html.twig │ └── dashboard │ │ └── components │ │ └── motd.html.twig │ ├── components │ └── header │ │ └── user_balance.html.twig │ ├── email │ ├── payment_success.html.twig │ ├── footer.html.twig │ ├── reset_password.html.twig │ └── email_verification.html.twig │ ├── template.json │ ├── bundles │ ├── TwigBundle │ │ └── Exception │ │ │ └── components │ │ │ └── error_footer.html.twig │ └── EasyAdminBundle │ │ └── flash_messages.html.twig │ └── sso │ └── redirect.html.twig ├── .github ├── ISSUE_TEMPLATE │ ├── custom.md │ ├── feature_request.md │ └── bug_report.md └── FUNDING.yml ├── phpstan.dist.neon ├── .dockerignore ├── .env.test ├── tests └── bootstrap.php ├── docker ├── php │ └── www.conf └── supervisor │ └── supervisord.conf ├── bin ├── console └── phpunit └── .gitignore /plugins/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /migrations/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/plugins/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Core/Entity/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/uploads/avatars/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/uploads/products/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/uploads/settings/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Core/Controller/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Core/Repository/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/uploads/categories/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Core/Resources/translations/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config/packages/vich_uploader.yaml: -------------------------------------------------------------------------------- 1 | vich_uploader: 2 | db_driver: orm -------------------------------------------------------------------------------- /config/packages/mailer.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | mailer: 3 | dsn: '%env(MAILER_DSN)%' 4 | -------------------------------------------------------------------------------- /themes/default/panel/crud/user_account/edit.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@EasyAdmin/crud/edit.html.twig' %} 2 | 3 | -------------------------------------------------------------------------------- /config/packages/property_info.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | property_info: 3 | with_constructor_extractor: true 4 | -------------------------------------------------------------------------------- /config/routes/security.yaml: -------------------------------------------------------------------------------- 1 | _security_logout: 2 | resource: security.route_loader.logout 3 | type: service 4 | -------------------------------------------------------------------------------- /public/assets/img/logo/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PteroCA-Org/panel/HEAD/public/assets/img/logo/logo.png -------------------------------------------------------------------------------- /config/packages/translation.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | default_locale: en 3 | translator: 4 | fallbacks: ['en'] 5 | -------------------------------------------------------------------------------- /public/assets/img/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PteroCA-Org/panel/HEAD/public/assets/img/favicon/favicon.ico -------------------------------------------------------------------------------- /public/assets/img/placeholders/300x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PteroCA-Org/panel/HEAD/public/assets/img/placeholders/300x150.png -------------------------------------------------------------------------------- /public/assets/img/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PteroCA-Org/panel/HEAD/public/assets/img/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /public/assets/img/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PteroCA-Org/panel/HEAD/public/assets/img/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /src/Core/Resources/config/twig.yaml: -------------------------------------------------------------------------------- 1 | twig: 2 | paths: 3 | '%kernel.project_dir%/src/Core/Resources/templates': core_templates 4 | -------------------------------------------------------------------------------- /public/assets/img/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PteroCA-Org/panel/HEAD/public/assets/img/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /public/assets/theme/default/fonts/Inter-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PteroCA-Org/panel/HEAD/public/assets/theme/default/fonts/Inter-Bold.woff2 -------------------------------------------------------------------------------- /public/assets/theme/default/fonts/Poppins-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PteroCA-Org/panel/HEAD/public/assets/theme/default/fonts/Poppins-Bold.ttf -------------------------------------------------------------------------------- /public/assets/img/favicon/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PteroCA-Org/panel/HEAD/public/assets/img/favicon/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/assets/img/favicon/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PteroCA-Org/panel/HEAD/public/assets/img/favicon/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/assets/theme/default/fonts/Inter-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PteroCA-Org/panel/HEAD/public/assets/theme/default/fonts/Inter-Medium.woff2 -------------------------------------------------------------------------------- /public/assets/theme/default/fonts/Inter-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PteroCA-Org/panel/HEAD/public/assets/theme/default/fonts/Inter-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/theme/default/fonts/Inter-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PteroCA-Org/panel/HEAD/public/assets/theme/default/fonts/Inter-SemiBold.woff2 -------------------------------------------------------------------------------- /public/assets/theme/default/fonts/Poppins-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PteroCA-Org/panel/HEAD/public/assets/theme/default/fonts/Poppins-SemiBold.ttf -------------------------------------------------------------------------------- /config/routes/framework.yaml: -------------------------------------------------------------------------------- 1 | when@dev: 2 | _errors: 3 | resource: '@FrameworkBundle/Resources/config/routing/errors.xml' 4 | prefix: /_error 5 | -------------------------------------------------------------------------------- /src/Core/Handler/HandlerInterface.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ app.user.balance|number_format(2, ',', ' ')}} {{ get_currency() }} 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/Core/Enum/ServerStatusEnum.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ 'pteroca.servers.no_servers'|trans }} 4 | 5 | {{ 'pteroca.servers.click_to_buy'|trans }} 6 | 7 | -------------------------------------------------------------------------------- /config/packages/csrf.yaml: -------------------------------------------------------------------------------- 1 | # Enable stateless CSRF protection for forms and logins/logouts 2 | framework: 3 | form: 4 | csrf_protection: 5 | token_id: submit 6 | 7 | csrf_protection: 8 | stateless_token_ids: 9 | - submit 10 | - authenticate 11 | - logout 12 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | bootEnv(dirname(__DIR__).'/.env'); 9 | } 10 | 11 | if ($_SERVER['APP_DEBUG']) { 12 | umask(0000); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /config/packages/twig.yaml: -------------------------------------------------------------------------------- 1 | twig: 2 | file_name_pattern: '*.twig' 3 | paths: 4 | '%kernel.project_dir%/themes/default': default_theme 5 | form_themes: 6 | - 'bootstrap_5_layout.html.twig' 7 | - 'form/bootstrap_5_custom.html.twig' 8 | 9 | when@test: 10 | twig: 11 | strict_variables: true 12 | -------------------------------------------------------------------------------- /src/Core/Enum/ServerStateEnum.php: -------------------------------------------------------------------------------- 1 | 5 | {{ 'pteroca.cart_topup.title'|trans }} 6 | 7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /src/Core/Entity/Payment.php: -------------------------------------------------------------------------------- 1 | 4 | {{ 'pteroca.email.payment.payment_received'|trans }} {{ amount|number_format(2) }} {{ currency|upper }}.
5 | {{ 'pteroca.email.payment.balance_updated'|trans }} {{ amount|number_format(2) }} {{ internalCurrency }}. 6 |

7 | {% include 'email/footer.html.twig' %} -------------------------------------------------------------------------------- /src/Core/Exception/UserDoesNotHaveClientApiKeyException.php: -------------------------------------------------------------------------------- 1 | =8.2", 10 | "options": { 11 | "supportDarkMode": true, 12 | "supportCustomColors": true 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Core/DTO/Action/Result/RegisterUserActionResult.php: -------------------------------------------------------------------------------- 1 | %s', 11 | $this->translator->trans('pteroca.system.experimental_feature'), 12 | ); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Core/Controller/Panel/Setting/PterodactylSettingCrudController.php: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Core/DTO/Pterodactyl/Credentials.php: -------------------------------------------------------------------------------- 1 | url; 16 | } 17 | 18 | public function getApiKey(): string 19 | { 20 | return $this->apiKey; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Core/Tests/Unit/Service/LocaleServiceTest.php: -------------------------------------------------------------------------------- 1 | getAvailableLocales(); 15 | 16 | $this->assertNotEmpty($result); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Core/DTO/SystemVersionDTO.php: -------------------------------------------------------------------------------- 1 | requestStack->getCurrentRequest(); 16 | return $request?->getClientIp(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Core/Controller/DefaultController.php: -------------------------------------------------------------------------------- 1 | redirect($this->generateUrl('app_login')); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Core/DTO/ServerVariableDTO.php: -------------------------------------------------------------------------------- 1 | supportDarkMode; 15 | } 16 | 17 | public function isSupportCustomColors(): bool 18 | { 19 | return $this->supportCustomColors; 20 | } 21 | } -------------------------------------------------------------------------------- /src/Core/Service/Email/ClientPanelUrlResolverService.php: -------------------------------------------------------------------------------- 1 | pterodactylRedirectService->getBasePanelUrl(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /themes/default/email/footer.html.twig: -------------------------------------------------------------------------------- 1 | {% trans_default_domain 'messages' %} 2 |

3 | {{ 'pteroca.email.general.best_regards'|trans }},
4 | {{ get_title() }} 5 |

6 | 7 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/Core/Exception/Pterodactyl/PterodactylValidationException.php: -------------------------------------------------------------------------------- 1 | validationErrors = $errors; 12 | } 13 | 14 | public function getValidationErrors(): array 15 | { 16 | return $this->validationErrors; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Core/Enum/ProductPriceUnitEnum.php: -------------------------------------------------------------------------------- 1 | self::DAYS, 15 | 'pteroca.crud.product.hours' => self::HOURS, 16 | 'pteroca.crud.product.minutes' => self::MINUTES, 17 | ]; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Core/Enum/LanguageEnum.php: -------------------------------------------------------------------------------- 1 | plugin; 17 | } 18 | 19 | public function getPluginName(): string 20 | { 21 | return $this->plugin->getName(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Core/Event/Plugin/PluginEnabledEvent.php: -------------------------------------------------------------------------------- 1 | plugin; 18 | } 19 | 20 | public function getPluginName(): string 21 | { 22 | return $this->plugin->getName(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Core/Event/Plugin/PluginRegisteredEvent.php: -------------------------------------------------------------------------------- 1 | plugin; 17 | } 18 | 19 | public function getPluginName(): string 20 | { 21 | return $this->plugin->getName(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 4 | {{ 'pteroca.email.recovery.we_received_request'|trans }}
5 | {{ 'pteroca.email.recovery.click_link_to_reset'|trans }} 6 |

7 |

8 | {{ 'pteroca.email.recovery.reset_password'|trans }} 9 |

10 |

11 | {{ 'pteroca.email.recovery.link_valid'|trans }}
12 | {{ 'pteroca.email.recovery.if_not_requested'|trans }} 13 |

14 | {% include 'email/footer.html.twig' %} -------------------------------------------------------------------------------- /config/packages/framework.yaml: -------------------------------------------------------------------------------- 1 | # see https://symfony.com/doc/current/reference/configuration/framework.html 2 | framework: 3 | secret: '%env(APP_SECRET)%' 4 | 5 | session: 6 | cookie_secure: auto 7 | cookie_samesite: lax 8 | cookie_domain: null 9 | 10 | default_locale: en 11 | translator: 12 | default_path: '%kernel.project_dir%/translations' 13 | fallbacks: 14 | - en 15 | 16 | when@test: 17 | framework: 18 | test: true 19 | session: 20 | storage_factory_id: session.storage.factory.mock_file 21 | -------------------------------------------------------------------------------- /src/Core/DTO/ServerLogDTO.php: -------------------------------------------------------------------------------- 1 | 8 | 9 | {% endblock %} 10 | 11 | {% block body %} 12 |
13 |
14 | {{ pageContent|raw }} 15 |
16 |
17 | {% endblock %} -------------------------------------------------------------------------------- /src/Core/Exception/Plugin/PluginUploadException.php: -------------------------------------------------------------------------------- 1 | details = $details; 16 | } 17 | 18 | public function getDetails(): array 19 | { 20 | return $this->details; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Core/Service/Product/ProductPriceCalculatorService.php: -------------------------------------------------------------------------------- 1 | getType()->value === ProductPriceTypeEnum::SLOT->value && $slots !== null && $slots > 0) { 13 | return $price->getPrice() * $slots; 14 | } 15 | 16 | return $price->getPrice(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Core/DTO/PaginationDTO.php: -------------------------------------------------------------------------------- 1 | $this->currentPage, 20 | 'totalPages' => $this->totalPages, 21 | 'totalItems' => $this->totalItems, 22 | 'items' => $this->items, 23 | ]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Core/Enum/VoucherTypeEnum.php: -------------------------------------------------------------------------------- 1 | self::BALANCE_TOPUP, 15 | 'pteroca.crud.voucher.payment_discount' => self::PAYMENT_DISCOUNT, 16 | 'pteroca.crud.voucher.server_discount' => self::SERVER_DISCOUNT, 17 | ]; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Core/DTO/Pterodactyl/Application/PterodactylApiKey.php: -------------------------------------------------------------------------------- 1 | get('identifier'); 12 | } 13 | 14 | public function getSecretToken(): ?string 15 | { 16 | return $this->meta['secret_token'] ?? null; 17 | } 18 | 19 | public function getFullApiKey(): string 20 | { 21 | return sprintf('%s%s', $this->getIdentifier(), $this->getSecretToken()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Core/Handler/MakeThemeHandler.php: -------------------------------------------------------------------------------- 1 | makeThemeService->createTheme($this->themeMetadata); 18 | } 19 | 20 | public function setThemeMetadata(array $metadata): void 21 | { 22 | $this->themeMetadata = $metadata; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Core/DTO/Action/Result/UpdateServerActionResult.php: -------------------------------------------------------------------------------- 1 | messages[] = [ 16 | 'message' => $message, 17 | 'type' => $type->value, 18 | ]; 19 | } 20 | 21 | public function getMessages(): array 22 | { 23 | return $this->messages; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Core/Enum/CrudTemplateContextEnum.php: -------------------------------------------------------------------------------- 1 | request('GET', '/'); 14 | 15 | $this->assertResponseRedirects($client->getContainer()->get('router')->generate('app_login')); 16 | 17 | $client->followRedirect(); 18 | 19 | $this->assertSelectorExists('input[id="username"]'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Core/Event/Crud/CrudEntityDeletedEvent.php: -------------------------------------------------------------------------------- 1 | entityInstance; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Core/Event/Crud/CrudEntityPersistedEvent.php: -------------------------------------------------------------------------------- 1 | entityInstance; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Core/Event/Crud/CrudEntityUpdatedEvent.php: -------------------------------------------------------------------------------- 1 | entityInstance; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Core/Exception/Email/ProductPriceNotFoundException.php: -------------------------------------------------------------------------------- 1 | setDefaults([ 14 | 'data_class' => ProductPrice::class, 15 | 'empty_data' => function () { 16 | return (new ProductPrice()) 17 | ->setType(ProductPriceTypeEnum::SLOT); 18 | }, 19 | ]); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Core/Repository/ServerProductRepository.php: -------------------------------------------------------------------------------- 1 | getEntityManager()->persist($serverProduct); 19 | $this->getEntityManager()->flush(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Core/Form/ProductPriceFixedFormType.php: -------------------------------------------------------------------------------- 1 | setDefaults([ 14 | 'data_class' => ProductPrice::class, 15 | 'empty_data' => function () { 16 | return (new ProductPrice()) 17 | ->setType(ProductPriceTypeEnum::STATIC); 18 | }, 19 | ]); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Core/Form/ProductPriceDynamicFormType.php: -------------------------------------------------------------------------------- 1 | setDefaults([ 14 | 'data_class' => ProductPrice::class, 15 | 'empty_data' => function () { 16 | return (new ProductPrice()) 17 | ->setType(ProductPriceTypeEnum::ON_DEMAND); 18 | }, 19 | ]); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /src/Core/Controller/API/APIAbstractController.php: -------------------------------------------------------------------------------- 1 | value : $permission; 16 | 17 | if (!$this->isGranted($permissionCode)) { 18 | throw $this->createAccessDeniedException(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Core/Event/Plugin/PluginFaultedEvent.php: -------------------------------------------------------------------------------- 1 | plugin; 18 | } 19 | 20 | public function getPluginName(): string 21 | { 22 | return $this->plugin->getName(); 23 | } 24 | 25 | public function getReason(): string 26 | { 27 | return $this->reason; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /migrations/Version20250204125527.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE user ADD avatar_path VARCHAR(255) DEFAULT NULL'); 20 | } 21 | 22 | public function down(Schema $schema): void 23 | { 24 | $this->addSql('ALTER TABLE user DROP avatar_path'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /migrations/Version20251109014447.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE setting ADD nullable TINYINT(1) DEFAULT 0 NOT NULL'); 20 | } 21 | 22 | public function down(Schema $schema): void 23 | { 24 | $this->addSql('ALTER TABLE setting DROP nullable'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Core/Repository/ProductRepository.php: -------------------------------------------------------------------------------- 1 | getEntityManager()->persist($product); 19 | 20 | if ($flush) { 21 | $this->getEntityManager()->flush(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /migrations/Version20250128174115.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE product ADD banner_path VARCHAR(255) DEFAULT NULL'); 20 | } 21 | 22 | public function down(Schema $schema): void 23 | { 24 | $this->addSql('ALTER TABLE product DROP banner_path'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /migrations/Version20251011101804.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE server ADD name VARCHAR(255) DEFAULT NULL AFTER pterodactyl_server_id'); 20 | } 21 | 22 | public function down(Schema $schema): void 23 | { 24 | $this->addSql('ALTER TABLE server DROP name'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Core/Enum/OverwriteableCrudTemplatesEnum.php: -------------------------------------------------------------------------------- 1 | value; 21 | } 22 | return $templates; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Core/Enum/SettingContextEnum.php: -------------------------------------------------------------------------------- 1 | name)] = $case->value; 21 | } 22 | 23 | return $values; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /migrations/Version20250126190537.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE server ADD auto_renewal TINYINT(1) NOT NULL DEFAULT 0'); 20 | } 21 | 22 | public function down(Schema $schema): void 23 | { 24 | $this->addSql('ALTER TABLE server DROP auto_renewal'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Core/Entity/Panel/UserPayment.php: -------------------------------------------------------------------------------- 1 | getAmount(), strtoupper($this->getCurrency())); 19 | } 20 | 21 | public function getLastUpdate(): DateTimeInterface 22 | { 23 | return $this->getUpdatedAt() ?? $this->getCreatedAt(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /migrations/Version20240124203658.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE user ADD balance INT NOT NULL'); 23 | } 24 | 25 | public function down(Schema $schema): void 26 | { 27 | $this->addSql('ALTER TABLE user DROP balance'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /migrations/Version20250913222644.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE user ADD deleted_at DATETIME DEFAULT NULL'); 20 | } 21 | 22 | public function down(Schema $schema): void 23 | { 24 | $this->addSql('ALTER TABLE user DROP deleted_at'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Core/DTO/Email/ServerSuspensionContextDTO.php: -------------------------------------------------------------------------------- 1 | entityInstance; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Core/Event/Crud/CrudEntityUpdatingEvent.php: -------------------------------------------------------------------------------- 1 | entityInstance; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Core/Event/Crud/CrudEntityPersistingEvent.php: -------------------------------------------------------------------------------- 1 | entityInstance; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Core/Message/SendEmailMessage.php: -------------------------------------------------------------------------------- 1 | to; 18 | } 19 | 20 | public function getSubject(): string 21 | { 22 | return $this->subject; 23 | } 24 | 25 | public function getTemplate(): string 26 | { 27 | return $this->template; 28 | } 29 | 30 | public function getContext(): array 31 | { 32 | return $this->context; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /migrations/Version20251027130000.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE payment ADD gateway VARCHAR(50) NOT NULL DEFAULT \'stripe\''); 20 | } 21 | 22 | public function down(Schema $schema): void 23 | { 24 | $this->addSql('ALTER TABLE payment DROP gateway'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Core/Event/Plugin/PluginDiscoveredEvent.php: -------------------------------------------------------------------------------- 1 | pluginPath; 18 | } 19 | 20 | public function getManifest(): PluginManifestDTO 21 | { 22 | return $this->manifest; 23 | } 24 | 25 | public function getPluginName(): string 26 | { 27 | return $this->manifest->name; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /migrations/Version20241126171453.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE product ADD eggs_configuration LONGTEXT DEFAULT NULL AFTER eggs'); 20 | } 21 | 22 | public function down(Schema $schema): void 23 | { 24 | $this->addSql('ALTER TABLE product DROP eggs_configuration'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Core/Enum/SettingTypeEnum.php: -------------------------------------------------------------------------------- 1 | name))] = $case->value; 25 | } 26 | return $values; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Core/Event/Cli/SynchronizeData/DataSyncProcessStartedEvent.php: -------------------------------------------------------------------------------- 1 | startedAt; 21 | } 22 | 23 | public function getContext(): array 24 | { 25 | return $this->context; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Core/Repository/ServerProductPriceRepository.php: -------------------------------------------------------------------------------- 1 | getEntityManager()->persist($entity); 19 | 20 | if ($flush) { 21 | $this->getEntityManager()->flush(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Core/Controller/API/Admin/VersionController.php: -------------------------------------------------------------------------------- 1 | requirePermission(PermissionEnum::ACCESS_ADMIN_OVERVIEW); 18 | 19 | return new JsonResponse($systemVersionService->getVersionInformation()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Core/Event/Crud/CrudConfiguredEvent.php: -------------------------------------------------------------------------------- 1 | crud; 23 | } 24 | 25 | public function setCrud(Crud $crud): void 26 | { 27 | $this->crud = $crud; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /config/packages/cache.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | cache: 3 | # Unique name of your app: used to compute stable namespaces for cache keys. 4 | #prefix_seed: your_vendor_name/app_name 5 | 6 | # The "app" cache stores to the filesystem by default. 7 | # The data in this cache should persist between deploys. 8 | # Other options include: 9 | 10 | # Redis 11 | #app: cache.adapter.redis 12 | #default_redis_provider: redis://localhost 13 | 14 | # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues) 15 | #app: cache.adapter.apcu 16 | 17 | # Namespaced pools use the above "app" backend by default 18 | #pools: 19 | #my.dedicated.cache: null 20 | -------------------------------------------------------------------------------- /src/Core/MessageHandler/SendEmailMessageHandler.php: -------------------------------------------------------------------------------- 1 | mailerService->sendEmail( 20 | $message->getTo(), 21 | $message->getSubject(), 22 | $message->getTemplate(), 23 | $message->getContext() 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /migrations/Version20250311193917.php: -------------------------------------------------------------------------------- 1 | addSql('INSERT INTO setting (name, value, type, context) VALUES (\'is_configured\', \'0\', \'boolean\', \'hidden_settings\')'); 20 | 21 | } 22 | 23 | public function down(Schema $schema): void 24 | { 25 | $this->addSql('DELETE FROM setting WHERE name = \'is_configured\''); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /migrations/Version20241127122406.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE user ADD pterodactyl_user_api_key VARCHAR(255) DEFAULT NULL AFTER pterodactyl_user_id'); 20 | } 21 | 22 | public function down(Schema $schema): void 23 | { 24 | $this->addSql('ALTER TABLE user DROP pterodactyl_user_api_key'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Core/Event/Cli/SuspendUnpaidServers/SuspendUnpaidServersProcessStartedEvent.php: -------------------------------------------------------------------------------- 1 | startedAt; 21 | } 22 | 23 | public function getContext(): array 24 | { 25 | return $this->context; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Core/Event/Server/ServerUnsuspendedEvent.php: -------------------------------------------------------------------------------- 1 | serverId; 20 | } 21 | 22 | public function getUserId(): int 23 | { 24 | return $this->userId; 25 | } 26 | 27 | public function getPterodactylServerId(): int 28 | { 29 | return $this->pterodactylServerId; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Core/Enum/LogActionEnum.php: -------------------------------------------------------------------------------- 1 | settingService->getSetting(SettingEnum::GOOGLE_CAPTCHA_VERIFICATION->value); 19 | } 20 | 21 | public function validateCaptcha(string $captchaResponse): bool 22 | { 23 | return $this->captchaProvider->validateCaptcha($captchaResponse); 24 | } 25 | } -------------------------------------------------------------------------------- /migrations/Version20241227012239.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE product ADD allow_change_egg TINYINT(1) NOT NULL DEFAULT 0 AFTER eggs_configuration'); 20 | } 21 | 22 | public function down(Schema $schema): void 23 | { 24 | $this->addSql('ALTER TABLE product DROP allow_change_egg'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Core/DTO/Pterodactyl/Client/PterodactylDatabase.php: -------------------------------------------------------------------------------- 1 | host['address']; 18 | } 19 | 20 | public function getPort(): int 21 | { 22 | return $this->host['port']; 23 | } 24 | 25 | public function getPassword(): ?string 26 | { 27 | return $this->relationships['password']['attributes']['password'] ?? null; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /migrations/Version20240129135319.php: -------------------------------------------------------------------------------- 1 | addSql('CREATE TABLE setting (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, value VARCHAR(10240) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); 20 | } 21 | 22 | public function down(Schema $schema): void 23 | { 24 | $this->addSql('DROP TABLE setting'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /migrations/Version20251215100714.php: -------------------------------------------------------------------------------- 1 | addSql("UPDATE setting SET nullable = 1 WHERE name IN ('site_logo', 'site_favicon')"); 20 | } 21 | 22 | public function down(Schema $schema): void 23 | { 24 | $this->addSql("UPDATE setting SET nullable = 0 WHERE name IN ('site_logo', 'site_favicon')"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Core/Contract/Pterodactyl/Client/PterodactylDatabasesInterface.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | public function getDatabases(string $serverId, array $params = []): Collection; 16 | 17 | public function createDatabase(string $serverId, string $database, string $remote): PterodactylDatabase; 18 | 19 | public function rotatePassword(string $serverId, string $databaseId): PterodactylDatabase; 20 | 21 | public function deleteDatabase(string $serverId, string $databaseId): void; 22 | } 23 | -------------------------------------------------------------------------------- /migrations/Version20250106174956.php: -------------------------------------------------------------------------------- 1 | addSql('INSERT INTO setting (name, value, type) VALUES (\'pterodactyl_use_as_client_panel\', \'0\', \'boolean\')'); 20 | } 21 | 22 | public function down(Schema $schema): void 23 | { 24 | $this->addSql('DELETE FROM setting WHERE name = \'pterodactyl_use_as_client_panel\''); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Core/Controller/API/EggsController.php: -------------------------------------------------------------------------------- 1 | requirePermission(PermissionEnum::EDIT_PRODUCT); 20 | 21 | return new JsonResponse($this->serverEggService->prepareEggsDataByNest($nestId)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Core/Contract/Pterodactyl/Client/PterodactylNetworkInterface.php: -------------------------------------------------------------------------------- 1 | requirePermission(PermissionEnum::ACCESS_SETTINGS_THEME); 19 | 20 | return new JsonResponse($templateService->getTemplateInfo($templateName)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Core/Event/Server/ServerProductCreatedEvent.php: -------------------------------------------------------------------------------- 1 | serverProductId; 20 | } 21 | 22 | public function getServerId(): int 23 | { 24 | return $this->serverId; 25 | } 26 | 27 | public function getOriginalProductId(): int 28 | { 29 | return $this->originalProductId; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /migrations/Version20250127091507.php: -------------------------------------------------------------------------------- 1 | addSql("INSERT INTO `setting` (`name`, `value`, `type`, `context`) VALUES ('current_theme', 'default', 'text', 'theme_settings')"); 20 | } 21 | 22 | public function down(Schema $schema): void 23 | { 24 | $this->addSql("DELETE FROM `setting` WHERE `name` = 'current_theme'"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Core/DTO/Collection/ServerVariableCollection.php: -------------------------------------------------------------------------------- 1 | variables, function (ServerVariableDTO $variable) use ($envVariable) { 18 | return $variable->envVariable === $envVariable; 19 | }); 20 | $foundVariable = current($foundVariable); 21 | 22 | return $foundVariable ?: null; 23 | } 24 | 25 | public function all(): array 26 | { 27 | return $this->variables; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Core/Event/Crud/CrudActionsConfiguredEvent.php: -------------------------------------------------------------------------------- 1 | actions; 23 | } 24 | 25 | public function setActions(Actions $actions): void 26 | { 27 | $this->actions = $actions; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Core/Event/Crud/CrudFiltersConfiguredEvent.php: -------------------------------------------------------------------------------- 1 | filters; 23 | } 24 | 25 | public function setFilters(Filters $filters): void 26 | { 27 | $this->filters = $filters; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Core/Event/Voucher/VoucherDeletedEvent.php: -------------------------------------------------------------------------------- 1 | voucherId; 21 | } 22 | 23 | public function getVoucherCode(): string 24 | { 25 | return $this->voucherCode; 26 | } 27 | 28 | public function getContext(): array 29 | { 30 | return $this->context; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Core/Service/Pterodactyl/PterodactylExceptionHandler.php: -------------------------------------------------------------------------------- 1 | $exception->getMessage()]; 13 | 14 | if ($exception instanceof PterodactylApiException && $exception->getResponseBody()) { 15 | $pterodactylError = json_decode($exception->getResponseBody(), true); 16 | 17 | if (isset($pterodactylError['errors'][0]['detail'])) { 18 | $errorData['detail'] = $pterodactylError['errors'][0]['detail']; 19 | } 20 | } 21 | 22 | return $errorData; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Core/DTO/Pterodactyl/Client/PterodactylFile.php: -------------------------------------------------------------------------------- 1 | isFile; 18 | } 19 | 20 | public function getFormattedSize(): string 21 | { 22 | $units = ['B', 'KB', 'MB', 'GB', 'TB']; 23 | $size = $this->size; 24 | $unitIndex = 0; 25 | 26 | while ($size >= 1024 && $unitIndex < count($units) - 1) { 27 | $size /= 1024; 28 | $unitIndex++; 29 | } 30 | 31 | return round($size, 2) . ' ' . $units[$unitIndex]; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Core/Entity/ProductPrice.php: -------------------------------------------------------------------------------- 1 | product; 21 | } 22 | 23 | public function setProduct(?Product $product): self 24 | { 25 | $this->product = $product; 26 | return $this; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Core/Event/User/Registration/UserCreatedEvent.php: -------------------------------------------------------------------------------- 1 | userId; 23 | } 24 | 25 | public function getEmail(): string 26 | { 27 | return $this->email; 28 | } 29 | 30 | public function getContext(): array 31 | { 32 | return $this->context; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Core/DTO/ServerWebsocketDTO.php: -------------------------------------------------------------------------------- 1 | token; 18 | } 19 | 20 | public function getSocket(): ?string 21 | { 22 | return $this->socket; 23 | } 24 | 25 | public function getServer(): ?Server 26 | { 27 | return $this->server; 28 | } 29 | 30 | public function toArray(): array 31 | { 32 | return [ 33 | 'token' => $this->token, 34 | 'socket' => $this->socket, 35 | ]; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /migrations/Version20251207161731.php: -------------------------------------------------------------------------------- 1 | addSql(" 20 | INSERT INTO setting (name, value, type, context, hierarchy, nullable) VALUES 21 | ('telemetry_consent', '1', 'boolean', 'general_settings', 20, 0) 22 | "); 23 | } 24 | 25 | public function down(Schema $schema): void 26 | { 27 | $this->addSql("DELETE FROM setting WHERE name = 'telemetry_consent'"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Core/Event/User/Registration/UserEmailVerifiedEvent.php: -------------------------------------------------------------------------------- 1 | userId; 23 | } 24 | 25 | public function getEmail(): string 26 | { 27 | return $this->email; 28 | } 29 | 30 | public function getContext(): array 31 | { 32 | return $this->context; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /migrations/Version20250708142015.php: -------------------------------------------------------------------------------- 1 | addSql('INSERT INTO setting (name, value, type, context) VALUES (\'show_pterodactyl_logs_in_server_activity\', \'1\', \'boolean\', \'pterodactyl_settings\')'); 20 | } 21 | 22 | public function down(Schema $schema): void 23 | { 24 | $this->addSql('DELETE FROM setting WHERE name = \'show_pterodactyl_logs_in_server_activity\''); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /bin/phpunit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | = 80000) { 10 | require dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit'; 11 | } else { 12 | define('PHPUNIT_COMPOSER_INSTALL', dirname(__DIR__).'/vendor/autoload.php'); 13 | require PHPUNIT_COMPOSER_INSTALL; 14 | PHPUnit\TextUI\Command::main(); 15 | } 16 | } else { 17 | if (!is_file(dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php')) { 18 | echo "Unable to find the `simple-phpunit.php` script in `vendor/symfony/phpunit-bridge/bin/`.\n"; 19 | exit(1); 20 | } 21 | 22 | require dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php'; 23 | } 24 | -------------------------------------------------------------------------------- /src/Core/Repository/ProductPriceRepository.php: -------------------------------------------------------------------------------- 1 | getEntityManager()->persist($productPrice); 19 | 20 | if ($flush) { 21 | $this->getEntityManager()->flush(); 22 | } 23 | } 24 | 25 | public function flush(): void 26 | { 27 | $this->getEntityManager()->flush(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Core/Contract/Pterodactyl/Client/PterodactylClientAdapterInterface.php: -------------------------------------------------------------------------------- 1 | value, 20 | $targetState->value 21 | ); 22 | 23 | if ($reason !== '') { 24 | $message .= ". Reason: $reason"; 25 | } 26 | 27 | parent::__construct($message); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /themes/default/email/email_verification.html.twig: -------------------------------------------------------------------------------- 1 | {% trans_default_domain 'messages' %} 2 | {% set title = 'pteroca.email.verification.title'|trans %} 3 | {% include 'email/header.html.twig' %} 4 | 5 |

6 | {{ 'pteroca.email.verification.message'|trans({'%siteName%': siteName}) }} 7 |

8 | 9 |

10 | 11 | {{ 'pteroca.email.verification.verify_button'|trans }} 12 | 13 |

14 | 15 |

16 | {{ 'pteroca.email.verification.alternative_text'|trans }}
17 | {{ verificationUrl }} 18 |

19 | 20 |

21 | {{ 'pteroca.email.verification.footer_text'|trans({'%siteName%': siteName, '%siteUrl%': siteUrl}) }} 22 |

23 | 24 | {% include 'email/footer.html.twig' %} 25 | -------------------------------------------------------------------------------- /themes/default/sso/redirect.html.twig: -------------------------------------------------------------------------------- 1 | {% block head_stylesheets %} 2 | 3 | {% endblock %} 4 | 5 | {% block head_favicon %} 6 | 7 | {% endblock %} 8 | 9 | {% block wrapper_wrapper %} 10 |
11 | 12 | 13 |
14 | {% endblock %} 15 | 16 | {% block body_javascript %} 17 | 22 | {% endblock %} 23 | -------------------------------------------------------------------------------- /src/Core/Event/Plugin/PluginUpdatedEvent.php: -------------------------------------------------------------------------------- 1 | plugin; 19 | } 20 | 21 | public function getPluginName(): string 22 | { 23 | return $this->plugin->getName(); 24 | } 25 | 26 | public function getOldVersion(): string 27 | { 28 | return $this->oldVersion; 29 | } 30 | 31 | public function getNewVersion(): string 32 | { 33 | return $this->newVersion; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /migrations/Version20250309181442.php: -------------------------------------------------------------------------------- 1 | addSql('CREATE INDEX IDX_5C7E2D3A7D3656A4 ON server_log (created_at)'); 20 | $this->addSql('CREATE INDEX IDX_1F1B251A7D3656A4 ON log (created_at)'); 21 | } 22 | 23 | public function down(Schema $schema): void 24 | { 25 | $this->addSql('DROP INDEX IDX_5C7E2D3A7D3656A4 ON server_log'); 26 | $this->addSql('DROP INDEX IDX_1F1B251A7D3656A4 ON log'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Core/Event/AbstractDomainEvent.php: -------------------------------------------------------------------------------- 1 | eventId = $eventId ?? Uuid::v4()->toString(); 17 | $this->occurredAt = new DateTimeImmutable(); 18 | } 19 | 20 | public function getEventId(): string 21 | { 22 | return $this->eventId; 23 | } 24 | 25 | public function getOccurredAt(): DateTimeImmutable 26 | { 27 | return $this->occurredAt; 28 | } 29 | 30 | public function getSchemaVersion(): string 31 | { 32 | return $this->schemaVersion; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /migrations/Version20251220010323.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE category ADD priority INT NOT NULL DEFAULT 0 AFTER name'); 20 | $this->addSql('ALTER TABLE product ADD priority INT NOT NULL DEFAULT 0 AFTER is_active'); 21 | } 22 | 23 | public function down(Schema $schema): void 24 | { 25 | $this->addSql('ALTER TABLE category DROP priority'); 26 | $this->addSql('ALTER TABLE product DROP priority'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Core/DTO/PaymentSessionDTO.php: -------------------------------------------------------------------------------- 1 | id; 18 | } 19 | 20 | public function getAmountTotal(): float 21 | { 22 | return $this->amountTotal; 23 | } 24 | 25 | public function getCurrency(): string 26 | { 27 | return $this->currency; 28 | } 29 | 30 | public function getPaymentStatus(): string 31 | { 32 | return $this->paymentStatus; 33 | } 34 | 35 | public function getUrl(): ?string 36 | { 37 | return $this->url; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /migrations/Version20240909174033.php: -------------------------------------------------------------------------------- 1 | addSql('INSERT INTO setting (name, type, value) VALUES (?, ?, ?)', [ 20 | 'terms_of_service', 21 | 'twig', 22 | '

Terms of service

You can set content of this page in settings.

', 23 | ]); 24 | } 25 | 26 | public function down(Schema $schema): void 27 | { 28 | $this->addSql('DELETE FROM setting WHERE name = ?', ['terms_of_service']); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Core/Contract/ProductPriceInterface.php: -------------------------------------------------------------------------------- 1 | userId; 21 | } 22 | 23 | public function getServerId(): int 24 | { 25 | return $this->serverId; 26 | } 27 | 28 | public function getPriceId(): int 29 | { 30 | return $this->priceId; 31 | } 32 | 33 | public function getSlots(): ?int 34 | { 35 | return $this->slots; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Core/Event/User/Registration/UserAboutToBeCreatedEvent.php: -------------------------------------------------------------------------------- 1 | user; 23 | } 24 | 25 | public function getEmail(): string 26 | { 27 | return $this->user->getEmail(); 28 | } 29 | 30 | public function getRoles(): array 31 | { 32 | return $this->user->getRoles(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Core/Enum/ServerLogActionEnum.php: -------------------------------------------------------------------------------- 1 | startedAt; 22 | } 23 | 24 | public function getEmail(): string 25 | { 26 | return $this->email; 27 | } 28 | 29 | public function getContext(): array 30 | { 31 | return $this->context; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /migrations/Version20240812195530.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE log ADD ip_address VARCHAR(255) NOT NULL'); 24 | } 25 | 26 | public function down(Schema $schema): void 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->addSql('ALTER TABLE log DROP ip_address'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /migrations/Version20240825133509.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE user ADD is_blocked TINYINT(1) NOT NULL'); 24 | } 25 | 26 | public function down(Schema $schema): void 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->addSql('ALTER TABLE user DROP is_blocked'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /migrations/Version20250708170843.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE product ADD threads VARCHAR(255) DEFAULT NULL'); 20 | 21 | $this->addSql('ALTER TABLE server_product ADD threads VARCHAR(255) DEFAULT NULL'); 22 | } 23 | 24 | public function down(Schema $schema): void 25 | { 26 | $this->addSql('ALTER TABLE server_product DROP threads'); 27 | 28 | $this->addSql('ALTER TABLE product DROP threads'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Core/Event/Cart/CartTopUpDataLoadedEvent.php: -------------------------------------------------------------------------------- 1 | userId; 21 | } 22 | 23 | public function getAmount(): float 24 | { 25 | return $this->amount; 26 | } 27 | 28 | public function getCurrency(): string 29 | { 30 | return $this->currency; 31 | } 32 | 33 | public function getContext(): array 34 | { 35 | return $this->context; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /migrations/Version20240730183226.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE product ADD nest INT DEFAULT NULL AFTER nodes'); 24 | } 25 | 26 | public function down(Schema $schema): void 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->addSql('ALTER TABLE product DROP nest'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /migrations/Version20240808175110.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE user ADD is_verified TINYINT(1) NOT NULL'); 24 | } 25 | 26 | public function down(Schema $schema): void 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->addSql('ALTER TABLE user DROP is_verified'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /migrations/Version20250705224050.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE product ADD schedules INT NOT NULL DEFAULT 10'); 20 | 21 | $this->addSql('ALTER TABLE server_product ADD schedules INT NOT NULL DEFAULT 10'); 22 | } 23 | 24 | public function down(Schema $schema): void 25 | { 26 | $this->addSql('ALTER TABLE server_product DROP schedules'); 27 | 28 | $this->addSql('ALTER TABLE product DROP schedules'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Core/Event/Cart/CartRenewPageAccessedEvent.php: -------------------------------------------------------------------------------- 1 | userId; 21 | } 22 | 23 | public function getServerId(): int 24 | { 25 | return $this->serverId; 26 | } 27 | 28 | public function getServerName(): string 29 | { 30 | return $this->serverName; 31 | } 32 | 33 | public function getContext(): array 34 | { 35 | return $this->context; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Core/Event/Server/ServerPurchaseCompletedEvent.php: -------------------------------------------------------------------------------- 1 | serverId; 21 | } 22 | 23 | public function getUserId(): int 24 | { 25 | return $this->userId; 26 | } 27 | 28 | public function getProductId(): int 29 | { 30 | return $this->productId; 31 | } 32 | 33 | public function getPricePaid(): float 34 | { 35 | return $this->pricePaid; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | ###> symfony/framework-bundle ### 3 | /.env 4 | /.env.local 5 | /.env.local.php 6 | /.env.*.local 7 | /config/secrets/prod/prod.decrypt.private.php 8 | /public/bundles/ 9 | /public/uploads/**/* 10 | !public/uploads/**/.gitkeep 11 | /public/plugins/**/* 12 | !public/plugins/.gitkeep 13 | /var/ 14 | /vendor/ 15 | /.idea 16 | ###< symfony/framework-bundle ### 17 | 18 | ###> symfony/phpunit-bridge ### 19 | .phpunit.result.cache 20 | /phpunit.xml 21 | ###< symfony/phpunit-bridge ### 22 | 23 | ###> phpunit/phpunit ### 24 | /phpunit.xml 25 | .phpunit.result.cache 26 | junit.xml 27 | ###< phpunit/phpunit ### 28 | 29 | ###> phpstan/phpstan ### 30 | phpstan.neon 31 | ###< phpstan/phpstan ### 32 | 33 | ###> pteroca/plugin-system ### 34 | # Ignore plugin contents but track the structure 35 | /plugins/*/ 36 | !plugins/.gitkeep 37 | ###< pteroca/plugin-system ### 38 | 39 | ###> custom ### 40 | CLAUDE.md 41 | docs/ 42 | ###< custom ### 43 | -------------------------------------------------------------------------------- /migrations/Version20240803231552.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE user ADD pterodactyl_user_id INT NOT NULL'); 24 | } 25 | 26 | public function down(Schema $schema): void 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->addSql('ALTER TABLE user DROP pterodactyl_user_id'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /migrations/Version20240804130207.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE category ADD image_path VARCHAR(255) DEFAULT NULL'); 24 | } 25 | 26 | public function down(Schema $schema): void 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->addSql('ALTER TABLE category DROP image_path'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /migrations/Version20240804133717.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE product ADD image_path VARCHAR(255) DEFAULT NULL'); 24 | } 25 | 26 | public function down(Schema $schema): void 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->addSql('ALTER TABLE product DROP image_path'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /migrations/Version20240804192020.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE category ADD description LONGTEXT DEFAULT NULL'); 24 | } 25 | 26 | public function down(Schema $schema): void 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->addSql('ALTER TABLE category DROP description'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Core/DTO/Pterodactyl/Client/PterodactylApiKey.php: -------------------------------------------------------------------------------- 1 | get('identifier'); 12 | } 13 | 14 | public function getDescription(): ?string 15 | { 16 | return $this->get('description'); 17 | } 18 | 19 | public function getAllowedIps(): ?array 20 | { 21 | return $this->get('allowed_ips'); 22 | } 23 | 24 | public function getLastUsedAt(): ?string 25 | { 26 | return $this->get('last_used_at'); 27 | } 28 | 29 | public function getCreatedAt(): ?string 30 | { 31 | return $this->get('created_at'); 32 | } 33 | 34 | public function getSecretToken(): ?string 35 | { 36 | return $this->get('secret_token'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Core/Event/Cart/CartConfigurePageAccessedEvent.php: -------------------------------------------------------------------------------- 1 | userId; 21 | } 22 | 23 | public function getProductId(): int 24 | { 25 | return $this->productId; 26 | } 27 | 28 | public function getProductName(): string 29 | { 30 | return $this->productName; 31 | } 32 | 33 | public function getContext(): array 34 | { 35 | return $this->context; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Core/EventSubscriber/User/UserRegistrationSubscriber.php: -------------------------------------------------------------------------------- 1 | 'onUserRegistered', 19 | ]; 20 | } 21 | 22 | public function onUserRegistered(UserRegisteredEvent $event): void 23 | { 24 | if (!$event->isVerified()) { 25 | $this->userEmailService->sendVerificationEmail($event->getUserId(), $event->getEmail()); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Core/Repository/VoucherRepository.php: -------------------------------------------------------------------------------- 1 | getEntityManager()->persist($voucher); 19 | $this->getEntityManager()->flush(); 20 | } 21 | 22 | public function getVoucherByCode(string $code): ?Voucher 23 | { 24 | return $this->createQueryBuilder('v') 25 | ->andWhere('v.code = :code') 26 | ->setParameter('code', $code) 27 | ->getQuery() 28 | ->getOneOrNullResult(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /migrations/Version20240730175747.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE product ADD nodes LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:simple_array)\''); 24 | } 25 | 26 | public function down(Schema $schema): void 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->addSql('ALTER TABLE product DROP nodes'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /migrations/Version20240730180609.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE product ADD eggs LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:simple_array)\''); 24 | } 25 | 26 | public function down(Schema $schema): void 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->addSql('ALTER TABLE product DROP eggs'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /migrations/Version20240730194105.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE product CHANGE `databases` db_count INT NOT NULL'); 24 | } 25 | 26 | public function down(Schema $schema): void 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->addSql('ALTER TABLE product CHANGE db_count `databases` INT NOT NULL'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /migrations/Version20240803231415.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE user ADD name VARCHAR(255) NOT NULL, ADD surname VARCHAR(255) NOT NULL'); 24 | } 25 | 26 | public function down(Schema $schema): void 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->addSql('ALTER TABLE user DROP name, DROP surname'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /migrations/Version20240803235341.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE server ADD pterodactyl_server_identifier VARCHAR(255) NOT NULL'); 24 | } 25 | 26 | public function down(Schema $schema): void 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->addSql('ALTER TABLE server DROP pterodactyl_server_identifier'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Core/Contract/Pterodactyl/Application/PterodactylNestsInterface.php: -------------------------------------------------------------------------------- 1 | 3 |
4 | {% if serverData.pterodactylClientServer and serverData.pterodactylClientAccount %} 5 | {% include 'panel/server/tabs/settings/components/sftp_details.html.twig' %} 6 | {% endif %} 7 | {% if hasServerPermission(serverData.serverPermissions, 'settings.rename') %} 8 | {% include 'panel/server/tabs/settings/components/change_server_details.html.twig' %} 9 | {% endif %} 10 | {% if hasServerPermission(serverData.serverPermissions, 'settings.reinstall') %} 11 | {% include 'panel/server/tabs/settings/components/reinstall_server.html.twig' %} 12 | {% endif %} 13 | {% include 'panel/server/tabs/settings/components/extend_server.html.twig' %} 14 |
15 | 16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /migrations/Version20240904184555.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE product CHANGE category_id category_id INT DEFAULT NULL'); 24 | } 25 | 26 | public function down(Schema $schema): void 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->addSql('ALTER TABLE product CHANGE category_id category_id INT NOT NULL'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Core/Event/Server/Tab/ServerTabsCollectedEvent.php: -------------------------------------------------------------------------------- 1 | registry; 23 | } 24 | 25 | public function getTabContext(): ServerTabContext 26 | { 27 | return $this->tabContext; 28 | } 29 | 30 | public function getContext(): array 31 | { 32 | return $this->context; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Core/Event/Cli/DeleteInactiveServers/DeleteInactiveServersProcessStartedEvent.php: -------------------------------------------------------------------------------- 1 | startedAt; 22 | } 23 | 24 | public function getDaysAfterExpiration(): int 25 | { 26 | return $this->daysAfterExpiration; 27 | } 28 | 29 | public function getContext(): array 30 | { 31 | return $this->context; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Core/Event/Store/StoreAccessedEvent.php: -------------------------------------------------------------------------------- 1 | userId; 19 | } 20 | 21 | public function getContext(): array 22 | { 23 | return $this->context; 24 | } 25 | 26 | public function getIp(): ?string 27 | { 28 | return $this->context['ip'] ?? null; 29 | } 30 | 31 | public function getUserAgent(): ?string 32 | { 33 | return $this->context['userAgent'] ?? null; 34 | } 35 | 36 | public function getLocale(): ?string 37 | { 38 | return $this->context['locale'] ?? null; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Core/Contract/Pterodactyl/Client/PterodactylBackupsInterface.php: -------------------------------------------------------------------------------- 1 | $this->identifier, 24 | 'name' => $this->name, 25 | 'description' => $this->description, 26 | 'ip' => $this->ip, 27 | 'limits' => $this->limits, 28 | 'featureLimits' => $this->featureLimits, 29 | 'egg' => $this->egg, 30 | 'state' => $this->state?->value, 31 | ]; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Core/Repository/LogRepository.php: -------------------------------------------------------------------------------- 1 | getEntityManager()->persist($log); 20 | $this->getEntityManager()->flush(); 21 | } 22 | 23 | public function deleteOldLogs(DateTimeInterface $cutoffDate): int 24 | { 25 | $qb = $this->createQueryBuilder('l') 26 | ->delete() 27 | ->where('l.createdAt < :cutoffDate') 28 | ->setParameter('cutoffDate', $cutoffDate); 29 | 30 | return $qb->getQuery()->execute(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Core/Service/Pterodactyl/PterodactylUsernameService.php: -------------------------------------------------------------------------------- 1 | pterodactylApplicationService 19 | ->getApplicationApi() 20 | ->users() 21 | ->getAllUsers(['filter' => ['username' => $username]]); 22 | 23 | if (!$users->isEmpty()) { 24 | $username = sprintf('%s%d', $username, rand(1, 999)); 25 | return $this->generateUsername($username); 26 | } 27 | 28 | return $username; 29 | } 30 | } -------------------------------------------------------------------------------- /src/Core/Trait/GetUserTrait.php: -------------------------------------------------------------------------------- 1 | getUser(); 30 | $userId = $user?->getId(); 31 | 32 | if ($userId === null) { 33 | throw new LogicException('User ID cannot be null in authenticated context'); 34 | } 35 | 36 | return $userId; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /migrations/Version20240825110754.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE user CHANGE pterodactyl_user_id pterodactyl_user_id INT DEFAULT NULL'); 24 | } 25 | 26 | public function down(Schema $schema): void 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->addSql('ALTER TABLE user CHANGE pterodactyl_user_id pterodactyl_user_id INT NOT NULL'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Core/Event/Server/ServerRenewalCompletedEvent.php: -------------------------------------------------------------------------------- 1 | serverId; 22 | } 23 | 24 | public function getUserId(): int 25 | { 26 | return $this->userId; 27 | } 28 | 29 | public function getPricePaid(): float 30 | { 31 | return $this->pricePaid; 32 | } 33 | 34 | public function getNewExpiresAt(): DateTimeInterface 35 | { 36 | return $this->newExpiresAt; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Core/Event/Server/ServersListAccessedEvent.php: -------------------------------------------------------------------------------- 1 | userId; 19 | } 20 | 21 | public function getContext(): array 22 | { 23 | return $this->context; 24 | } 25 | 26 | public function getIp(): ?string 27 | { 28 | return $this->context['ip'] ?? null; 29 | } 30 | 31 | public function getUserAgent(): ?string 32 | { 33 | return $this->context['userAgent'] ?? null; 34 | } 35 | 36 | public function getLocale(): ?string 37 | { 38 | return $this->context['locale'] ?? null; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /docker/supervisor/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | user=root 4 | logfile=/var/log/supervisor/supervisord.log 5 | pidfile=/var/run/supervisord.pid 6 | 7 | [program:php-fpm] 8 | command=php-fpm -F 9 | stdout_logfile=/var/log/supervisor/php-fpm.log 10 | stderr_logfile=/var/log/supervisor/php-fpm.log 11 | autorestart=true 12 | priority=5 13 | 14 | [program:nginx] 15 | command=nginx -g "daemon off;" 16 | stdout_logfile=/var/log/supervisor/nginx.log 17 | stderr_logfile=/var/log/supervisor/nginx.log 18 | autorestart=true 19 | priority=10 20 | 21 | [program:cron] 22 | command=cron -f 23 | stdout_logfile=/var/log/supervisor/cron.log 24 | stderr_logfile=/var/log/supervisor/cron.log 25 | autorestart=true 26 | priority=15 27 | 28 | [unix_http_server] 29 | file=/var/run/supervisor.sock 30 | chmod=0700 31 | 32 | [supervisorctl] 33 | serverurl=unix:///var/run/supervisor.sock 34 | 35 | [rpcinterface:supervisor] 36 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface 37 | -------------------------------------------------------------------------------- /migrations/Version20240805105949.php: -------------------------------------------------------------------------------- 1 | addSql('ALTER TABLE setting ADD type VARCHAR(50) NOT NULL, CHANGE value value LONGTEXT DEFAULT NULL'); 24 | } 25 | 26 | public function down(Schema $schema): void 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->addSql('ALTER TABLE setting DROP type, CHANGE value value VARCHAR(10240) NOT NULL'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Core/Event/Plugin/PluginIndexPageAccessedEvent.php: -------------------------------------------------------------------------------- 1 | userId; 19 | } 20 | 21 | public function getContext(): array 22 | { 23 | return $this->context; 24 | } 25 | 26 | public function getIp(): ?string 27 | { 28 | return $this->context['ip'] ?? null; 29 | } 30 | 31 | public function getUserAgent(): ?string 32 | { 33 | return $this->context['userAgent'] ?? null; 34 | } 35 | 36 | public function getLocale(): ?string 37 | { 38 | return $this->context['locale'] ?? null; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Core/Event/Server/ServerEntityCreatedEvent.php: -------------------------------------------------------------------------------- 1 | serverId; 22 | } 23 | 24 | public function getUserId(): int 25 | { 26 | return $this->userId; 27 | } 28 | 29 | public function getPterodactylServerId(): int 30 | { 31 | return $this->pterodactylServerId; 32 | } 33 | 34 | public function getExpiresAt(): DateTimeInterface 35 | { 36 | return $this->expiresAt; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [pteroca-com] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: pteroca # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: pteroca # Replace with a single Buy Me a Coffee username 14 | thanks_dev: # Replace with a single thanks.dev username 15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 16 | -------------------------------------------------------------------------------- /themes/default/bundles/EasyAdminBundle/flash_messages.html.twig: -------------------------------------------------------------------------------- 1 | {# @var ea \EasyCorp\Bundle\EasyAdminBundle\Provider\AdminContext #} 2 | {% set ea = ea() %} 3 | {% trans_default_domain null != ea ? ea.i18n.translationDomain : (translation_domain is defined ? translation_domain ?? 'messages') %} 4 | 5 | {% set flash_messages = app.flashes %} 6 | 7 | {% if flash_messages|length > 0 %} 8 |
9 | {% for label, messages in flash_messages %} 10 | {% for message in messages %} 11 | {# the message must be translated outside of the Twig component because 12 | the trans_default_domain value is ignored inside the component #} 13 | {% set translated_message = message|trans %} 14 | 15 | {{ translated_message|raw }} 16 | 17 | {% endfor %} 18 | {% endfor %} 19 |
20 | {% endif %} 21 | -------------------------------------------------------------------------------- /themes/default/panel/dashboard/components/motd.html.twig: -------------------------------------------------------------------------------- 1 | {% if motdEnabled %} 2 |
3 |
4 |
5 | 6 |
{{ motdTitle|raw }}
7 |
8 |
9 |
10 |
11 |
12 | 13 |
14 |
15 | {{ motdMessage|raw }} 16 |
17 |
18 |
19 |
20 | {% endif %} 21 | -------------------------------------------------------------------------------- /src/Core/Event/User/Registration/UserRegisteredEvent.php: -------------------------------------------------------------------------------- 1 | userId; 24 | } 25 | 26 | public function getEmail(): string 27 | { 28 | return $this->email; 29 | } 30 | 31 | public function isVerified(): bool 32 | { 33 | return $this->isVerified; 34 | } 35 | 36 | public function getContext(): array 37 | { 38 | return $this->context; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /src/Core/Event/Server/ServerCreatedOnPterodactylEvent.php: -------------------------------------------------------------------------------- 1 | userId; 21 | } 22 | 23 | public function getPterodactylServerId(): int 24 | { 25 | return $this->pterodactylServerId; 26 | } 27 | 28 | public function getPterodactylServerIdentifier(): string 29 | { 30 | return $this->pterodactylServerIdentifier; 31 | } 32 | 33 | public function getProductId(): int 34 | { 35 | return $this->productId; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Core/Event/Server/ServerEulaAcceptedEvent.php: -------------------------------------------------------------------------------- 1 | userId; 22 | } 23 | 24 | public function getServerId(): int 25 | { 26 | return $this->serverId; 27 | } 28 | 29 | public function getServerPterodactylIdentifier(): string 30 | { 31 | return $this->serverPterodactylIdentifier; 32 | } 33 | 34 | public function getContext(): array 35 | { 36 | return $this->context; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /migrations/Version20251215175124.php: -------------------------------------------------------------------------------- 1 | addSql(' 20 | DELETE s1 FROM setting s1 21 | INNER JOIN setting s2 22 | WHERE s1.name = s2.name 23 | AND s1.context = s2.context 24 | AND s1.id > s2.id 25 | '); 26 | 27 | $this->addSql('ALTER TABLE setting ADD UNIQUE KEY unique_setting_name_context (name, context)'); 28 | } 29 | 30 | public function down(Schema $schema): void 31 | { 32 | $this->addSql('ALTER TABLE setting DROP INDEX unique_setting_name_context'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Core/Event/Server/ServerExpirationExtendedEvent.php: -------------------------------------------------------------------------------- 1 | serverId; 22 | } 23 | 24 | public function getUserId(): int 25 | { 26 | return $this->userId; 27 | } 28 | 29 | public function getOldExpiresAt(): DateTimeInterface 30 | { 31 | return $this->oldExpiresAt; 32 | } 33 | 34 | public function getNewExpiresAt(): DateTimeInterface 35 | { 36 | return $this->newExpiresAt; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Core/Trait/CrudFlashMessagesTrait.php: -------------------------------------------------------------------------------- 1 | requestStack->getSession(); 16 | $usesDedupe = $session instanceof FlashBagAwareSessionInterface; 17 | 18 | foreach ($flashMessages as $flashMessage) { 19 | $type = $flashMessage['type'] ?? 'danger'; 20 | $message = $flashMessage['message']; 21 | 22 | if ($usesDedupe) { 23 | $existingMessages = $session->getFlashBag()->peek($type); 24 | if (in_array($message, $existingMessages, true)) { 25 | continue; 26 | } 27 | } 28 | 29 | $this->addFlash($type, $message); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Core/Event/Server/ServerDetailsRequestedEvent.php: -------------------------------------------------------------------------------- 1 | userId; 22 | } 23 | 24 | public function getServerId(): int 25 | { 26 | return $this->serverId; 27 | } 28 | 29 | public function getServerPterodactylIdentifier(): string 30 | { 31 | return $this->serverPterodactylIdentifier; 32 | } 33 | 34 | public function getContext(): array 35 | { 36 | return $this->context; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Core/Event/StoppableEventTrait.php: -------------------------------------------------------------------------------- 1 | propagationStopped; 14 | } 15 | 16 | public function stopPropagation(): void 17 | { 18 | $this->propagationStopped = true; 19 | } 20 | 21 | public function isRejected(): bool 22 | { 23 | return $this->rejected; 24 | } 25 | 26 | public function setRejected(bool $rejected, ?string $reason = null): void 27 | { 28 | $this->rejected = $rejected; 29 | $this->rejectionReason = $reason; 30 | 31 | if ($rejected) { 32 | $this->stopPropagation(); 33 | } 34 | } 35 | 36 | public function getRejectionReason(): ?string 37 | { 38 | return $this->rejectionReason; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Core/Event/User/Registration/UserRegistrationFailedEvent.php: -------------------------------------------------------------------------------- 1 | email; 24 | } 25 | 26 | public function getReason(): string 27 | { 28 | return $this->reason; 29 | } 30 | 31 | public function getStage(): string 32 | { 33 | return $this->stage; 34 | } 35 | 36 | public function getContext(): array 37 | { 38 | return $this->context; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Core/Factory/ServerVariableFactory.php: -------------------------------------------------------------------------------- 1 | 12 | */ 13 | public function createFromCollection(array $variables): array 14 | { 15 | $preparedVariables = []; 16 | 17 | foreach ($variables as $variable) { 18 | $variableRules = explode('|', $variable['rules']); 19 | 20 | $preparedVariables[] = new ServerVariableDTO( 21 | $variable['name'], 22 | $variable['description'], 23 | $variable['env_variable'], 24 | $variable['default_value'], 25 | $variable['server_value'], 26 | $variable['user_editable'], 27 | $variable['user_viewable'], 28 | $variableRules, 29 | ); 30 | } 31 | 32 | return $preparedVariables; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Core/Service/Server/ServerNestService.php: -------------------------------------------------------------------------------- 1 | pterodactylApplicationService 19 | ->getApplicationApi() 20 | ->nestEggs() 21 | ->all($nestId) 22 | ->toArray(); 23 | } 24 | 25 | public function getServerAvailableEggs(Server $server): array 26 | { 27 | $nestEggs = $this->getNestEggs($server->getServerProduct()->getNest()); 28 | 29 | return array_filter($nestEggs, function (array $egg) use ($server) { 30 | return in_array($egg['id'], $server->getServerProduct()->getEggs()); 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /config/services.yaml: -------------------------------------------------------------------------------- 1 | # This file is the entry point to configure your own services. 2 | # Files in the packages/ subdirectory configure your dependencies. 3 | 4 | # Learn more about services, parameters and containers: 5 | # https://symfony.com/doc/current/service_container.html 6 | 7 | parameters: 8 | 9 | services: 10 | _defaults: 11 | autowire: true # Automatically injects dependencies in your services. 12 | autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. 13 | 14 | # makes classes in src/ available to be used as services 15 | # this creates a service per class whose id is the fully-qualified class name 16 | # App\: 17 | # resource: '../src/*' 18 | # exclude: 19 | # - '../src/DependencyInjection/' 20 | # - '../src/Entity/' 21 | # - '../src/Kernel.php' 22 | 23 | # add more service definitions when explicit configuration is needed 24 | # please note that last definitions always *replace* previous ones 25 | -------------------------------------------------------------------------------- /src/Core/Event/Voucher/VoucherUpdateRequestedEvent.php: -------------------------------------------------------------------------------- 1 | voucher; 24 | } 25 | 26 | public function getVoucherId(): ?int 27 | { 28 | return $this->voucher->getId(); 29 | } 30 | 31 | public function getVoucherCode(): string 32 | { 33 | return $this->voucher->getCode(); 34 | } 35 | 36 | public function getContext(): array 37 | { 38 | return $this->context; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Core/Event/Voucher/VoucherDeletionRequestedEvent.php: -------------------------------------------------------------------------------- 1 | voucher; 24 | } 25 | 26 | public function getVoucherId(): ?int 27 | { 28 | return $this->voucher->getId(); 29 | } 30 | 31 | public function getVoucherCode(): string 32 | { 33 | return $this->voucher->getCode(); 34 | } 35 | 36 | public function getContext(): array 37 | { 38 | return $this->context; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Core/Service/Server/ServerConfiguration/AbstractServerConfiguration.php: -------------------------------------------------------------------------------- 1 | pterodactylApplicationService 23 | ->getApplicationApi() 24 | ->servers() 25 | ->getServer($server->getPterodactylServerId(), $include) 26 | ?->toArray(); 27 | 28 | if (empty($serverDetails)) { 29 | throw new Exception('Server not found'); 30 | } 31 | 32 | return $serverDetails; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Core/Event/Cli/CreateUser/UserCreationProcessStartedEvent.php: -------------------------------------------------------------------------------- 1 | startedAt; 23 | } 24 | 25 | public function getEmail(): string 26 | { 27 | return $this->email; 28 | } 29 | 30 | public function getRole(): string 31 | { 32 | return $this->role; 33 | } 34 | 35 | public function getContext(): array 36 | { 37 | return $this->context; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Core/Event/Server/Network/ServerAllocationCreatedEvent.php: -------------------------------------------------------------------------------- 1 | userId; 22 | } 23 | 24 | public function getServerId(): int 25 | { 26 | return $this->serverId; 27 | } 28 | 29 | public function getServerPterodactylIdentifier(): string 30 | { 31 | return $this->serverPterodactylIdentifier; 32 | } 33 | 34 | public function getContext(): array 35 | { 36 | return $this->context; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Core/Event/Server/ServerWebsocketTokenGeneratedEvent.php: -------------------------------------------------------------------------------- 1 | userId; 22 | } 23 | 24 | public function getServerId(): int 25 | { 26 | return $this->serverId; 27 | } 28 | 29 | public function getServerPterodactylIdentifier(): string 30 | { 31 | return $this->serverPterodactylIdentifier; 32 | } 33 | 34 | public function getContext(): array 35 | { 36 | return $this->context; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Core/Event/Server/ServerWebsocketTokenRequestedEvent.php: -------------------------------------------------------------------------------- 1 | userId; 22 | } 23 | 24 | public function getServerId(): int 25 | { 26 | return $this->serverId; 27 | } 28 | 29 | public function getServerPterodactylIdentifier(): string 30 | { 31 | return $this->serverPterodactylIdentifier; 32 | } 33 | 34 | public function getContext(): array 35 | { 36 | return $this->context; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Core/Enum/ViewNameEnum.php: -------------------------------------------------------------------------------- 1 | startedAt; 23 | } 24 | 25 | public function getLimit(): int 26 | { 27 | return $this->limit; 28 | } 29 | 30 | public function isDryRun(): bool 31 | { 32 | return $this->dryRun; 33 | } 34 | 35 | public function getContext(): array 36 | { 37 | return $this->context; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Core/Event/Server/ServerPurchaseValidatedEvent.php: -------------------------------------------------------------------------------- 1 | userId; 22 | } 23 | 24 | public function getProductId(): int 25 | { 26 | return $this->productId; 27 | } 28 | 29 | public function getEggId(): int 30 | { 31 | return $this->eggId; 32 | } 33 | 34 | public function getPriceId(): int 35 | { 36 | return $this->priceId; 37 | } 38 | 39 | public function getSlots(): ?int 40 | { 41 | return $this->slots; 42 | } 43 | } 44 | --------------------------------------------------------------------------------