update: Add custom domain support with automatic fallback validation - #73

Merged
Boy132 merged 2 commits into
pelican:mainfrom
FlexKleks:main
Jan 3, 2026
Merged

update: Add custom domain support with automatic fallback validation#73
Boy132 merged 2 commits into
pelican:mainfrom
FlexKleks:main

Conversation

@FlexKleks

@FlexKleksFlexKleks commented Jan 3, 2026

Copy link
Copy Markdown
Contributor

Hey, here's a change to my “PasteFox Share” plugin.

Changes

  • Add custom domain support for paste URLs
  • Add automatic API key validation (falls back to anonymous upload if key is invalid/expired)
  • Add automatic custom domain validation (falls back to pastefox.com if domain is inactive/removed)
  • Add translations for all settings page strings
  • Bump version to 1.1.0

Custom Domains

Users can now select a verified custom domain from their PasteFox account to use for paste URLs. The plugin automatically validates that the domain is still active before using it.

Fallback Behavior

If the configured API key or custom domain becomes unavailable, the plugin gracefully falls back to:

  • Anonymous uploads (7-day expiration, public visibility)
  • Default pastefox.com domain

Summary by CodeRabbit

  • New Features

    • Added Custom Domain support to share pastes from your own verified domain.
    • Domain selection now available in plugin settings (requires API key); verified domains shown, inactive ones disabled.
    • Automatic fallback to pastefox.com if a custom domain is unavailable.
  • Chores

    • Updated plugin version to 1.1.0.
    • Added translations and UI text for custom domain management.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitaiBot commented Jan 3, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds Custom Domain support to PasteFox Share: new config key, translations, README updates, plugin version bump, settings UI to fetch/choose verified domains via API, persistence of selection, and upload logic that validates API key and uses the custom domain or falls back to pastefox.com.

Changes

Cohort / File(s)Summary
Documentation & Manifest
pastefox-share/README.md, pastefox-share/plugin.json
README updated with Custom Domain docs; plugin version bumped from 1.0.01.1.0.
Configuration
pastefox-share/config/pastefox-share.php
New config entry: 'custom_domain' => env('PASTEFOX_CUSTOM_DOMAIN').
Translations
pastefox-share/lang/en/messages.php
Adds translation keys for Custom Domain UI and related helper/error texts (section_custom_domain, custom_domain, custom_domain_none, custom_domain_helper, custom_domain_no_api_key, custom_domain_fetch_error, custom_domain_inactive, etc.).
Settings UI & API integration
pastefox-share/src/PasteFoxSharePlugin.php
Adds HTTP client usage and getCustomDomainOptions() to fetch domains from https://pastefox.com/api/domains; settings form extended with a Select for custom_domain; saveSettings() persists choice to PASTEFOX_CUSTOM_DOMAIN.
Upload logic / Validation
pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php
Adds isApiKeyValid() and getActiveCustomDomain(); upload flow now conditionally includes X-API-Key and uses validated custom domain as base URL or falls back to https://pastefox.com; error handling and conditional payload/header logic added.

Sequence Diagrams

sequenceDiagram
participant User
participant Settings as Plugin Settings
participant API as PasteFox API
participant Env as Environment
participant Upload as UploadLogsAction
User->>Settings: Open settings
Settings->>API: GET /api/domains (X-API-Key if present)
API-->>Settings: Domain list (active/inactive)
Settings->>User: Render domain select (inactive → disabled)
User->>Settings: Select domain & Save
Settings->>Env: Persist PASTEFOX_CUSTOM_DOMAIN
Note over User,Upload: Later — user triggers paste upload
User->>Upload: Trigger upload
Upload->>Env: Read api_key & custom_domain
Upload->>API: Validate API key (isApiKeyValid)
Upload->>API: Verify configured domain (getActiveCustomDomain)
alt custom domain valid
Upload->>API: Create paste using custom domain (X-API-Key header)
else fallback
Upload->>API: Create paste at pastefox.com (no X-API-Key)
end
API-->>Upload: Returns paste URL
Upload-->>User: Show paste URL
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Add PasteFox Share plugin #63: Original PasteFox Share plugin introduction; modifies the same files/classes extended here (UploadLogsAction, PasteFoxSharePlugin, config, translations, manifest).

Suggested reviewers

  • lajczi
  • rmartinoscar

Poem

🐰 I sniffed the code, a domain to share,
Hopped through settings with API flair,
Verified names in dropdown air,
Fallback ready, so no despair,
Logs land safely — hop, share, and care!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 16.67% which is insufficient. The required threshold is 80.00%.You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main feature being added: custom domain support with automatic fallback validation, which aligns with all the changes across configuration, UI, translations, and logic.
✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php (2)

149-168: Consider caching API key validation results.

Every log upload triggers an HTTP request to validate the API key. For frequently accessed servers, this creates unnecessary load and latency. API keys rarely change, making them good candidates for caching.

Consider using Laravel's cache to store validation results for a reasonable TTL (e.g., 5-10 minutes):

protectedfunctionisApiKeyValid(?string$apiKey): bool
{
if (blank($apiKey)) {
returnfalse;
}
$cacheKey = 'pastefox_api_key_valid_' . hash('sha256', $apiKey);
returncache()->remember($cacheKey, 300, function () use ($apiKey) {
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
'Content-Type' => 'application/json',
])
->timeout(5)
->get('https://pastefox.com/api/domains')
->json();
return$response['success'] ?? false;
} catch (\Exception$e) {
returnfalse;
}
});
}

Note: If you implement the consolidated API call from the previous comment, apply caching to the consolidated method instead.


118-147: Silent failure in domain validation could hide configuration issues.

While graceful fallback is appropriate for availability issues, completely silent failure makes it difficult for administrators to diagnose why their custom domain isn't working (e.g., typo in domain name, domain not activated, API connectivity issues).

Consider logging a warning when the configured domain is invalid or inactive:

protectedfunctiongetActiveCustomDomain(?string$apiKey): ?string
{
$configuredDomain = config('pastefox-share.custom_domain');
if (blank($configuredDomain) || blank($apiKey)) {
returnnull;
}
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
'Content-Type' => 'application/json',
])
->timeout(5)
->get('https://pastefox.com/api/domains')
->json();
if ($response['success'] ?? false) {
foreach ($response['domains'] ?? [] as$domain) {
if ($domain['domain'] === $configuredDomain && ($domain['isActive'] ?? false)) {
return$configuredDomain;
}
}
+ // Domain configured but not found or inactive
+ logger()->warning("PasteFox custom domain '{$configuredDomain}' is not active, falling back to pastefox.com");
}
} catch (\Exception$e) {
- // Silently fail, fall back to default
+ logger()->warning("Failed to fetch PasteFox domains: {$e->getMessage()}");
}
returnnull;
}

This helps administrators identify configuration issues while maintaining the graceful fallback behavior.

pastefox-share/src/PasteFoxSharePlugin.php (1)

104-140: Add PHPDoc return type annotation to satisfy PHPStan.

The static analysis error indicates the return type lacks a value type specification. Additionally, the Content-Type header is unnecessary for GET requests.

🔎 Proposed fix
+ /**+ * @return array<string, string>+ */
protected function getCustomDomainOptions(): array
{
$options = ['' => trans('pastefox-share::messages.custom_domain_none')];
$apiKey = config('pastefox-share.api_key');
if (blank($apiKey)) {
return $options;
}
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
- 'Content-Type' => 'application/json',
])
->timeout(10)
->get('https://pastefox.com/api/domains')
->json();
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c2ca0f6 and e53dece.

📒 Files selected for processing (6)
  • pastefox-share/README.md
  • pastefox-share/config/pastefox-share.php
  • pastefox-share/lang/en/messages.php
  • pastefox-share/plugin.json
  • pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php
  • pastefox-share/src/PasteFoxSharePlugin.php
🧰 Additional context used
🪛 GitHub Check: PHPStan
pastefox-share/src/PasteFoxSharePlugin.php

[failure] 104-104:
Method FlexKleks\PasteFoxShare\PasteFoxSharePlugin::getCustomDomainOptions() return type has no value type specified in iterable type array.

🪛 markdownlint-cli2 (0.18.1)
pastefox-share/README.md

24-24: Bare URL used

(MD034, no-bare-urls)

🔇 Additional comments (7)
pastefox-share/plugin.json (1)

5-5: LGTM! Appropriate version bump.

The version increment to 1.1.0 correctly reflects the addition of custom domain support as a new feature.

pastefox-share/config/pastefox-share.php (1)

9-9: LGTM! Configuration entry follows established patterns.

The custom domain configuration is consistent with other optional settings in the file.

pastefox-share/lang/en/messages.php (1)

40-49: LGTM! Comprehensive translation coverage.

The translation keys are well-structured and provide clear, user-friendly messaging for the custom domain feature.

pastefox-share/README.md (2)

22-29: LGTM! Clear configuration documentation.

The updated settings table clearly documents all available configuration options including the new custom domain feature.


38-50: LGTM! Comprehensive custom domain documentation.

The documentation clearly explains:

  • How to set up custom domains
  • The verification process
  • Automatic fallback behavior

This provides users with the information needed to configure and use the feature.

pastefox-share/src/PasteFoxSharePlugin.php (2)

87-100: Well-structured conditional UI behavior.

The custom domain section properly gates functionality based on API key presence—disabling the select and showing appropriate helper text when no API key is configured. The disableOptionWhen pattern using the :disabled suffix cleanly prevents selection of inactive domains while still showing them in the dropdown.


150-150: LGTM!

Persistence of the new setting follows the established pattern. Per the AI summary, runtime validation in UploadLogsAction handles fallback when a configured domain becomes inactive.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
pastefox-share/src/PasteFoxSharePlugin.php (2)

138-140: Consider logging errors while maintaining graceful fallback.

Silent error handling prevents debugging issues with the API integration. Consider logging the exception while still returning default options for graceful degradation.

💡 Suggested refactor to add logging
 } catch (\Exception $e) {
- // Silently fail, just return default options+ \Log::warning('Failed to fetch custom domains from PasteFox API', [+ 'error' => $e->getMessage(),+ ]);
}

122-122: Consider extracting the API URL to a constant or config.

Hardcoding the API URL makes it harder to test or support different environments (staging, local development, etc.).

💡 Suggested refactor

Add to your config file:

'api_base_url' => env('PASTEFOX_API_URL', 'https://pastefox.com'),

Then update the code:

- ->get('https://pastefox.com/api/domains')+ ->get(config('pastefox-share.api_base_url') . '/api/domains')
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e53dece and d762559.

📒 Files selected for processing (1)
  • pastefox-share/src/PasteFoxSharePlugin.php
🔇 Additional comments (3)
pastefox-share/src/PasteFoxSharePlugin.php (3)

13-13: LGTM!

The Http facade import is correctly added to support the API call in getCustomDomainOptions().


153-153: LGTM!

The persistence of the custom domain setting follows the established pattern and is correctly implemented.


127-136: The logic is not inconsistent. The status field validates that the domain is registered in the PasteFox system (status === 'ACTIVE'), while isActive represents the user's preference to enable or disable the domain in their dashboard settings. These are complementary validation layers—one system-level, one user-level—not redundant checks.

Additionally, the :disabled suffix pattern is the proper Filament framework convention. Line 94 shows ->disableOptionWhen(fn (string $value): bool => str_ends_with($value, ':disabled')), which is the intended API for presenting disabled options in the select field. This is not a data/UI mixing issue but correct framework integration.

Likely an incorrect or invalid review comment.

Comment threadpastefox-share/src/PasteFoxSharePlugin.php
@Boy132
Boy132 merged commit 39f9c1f into pelican:mainJan 3, 2026
4 checks passed
@Boy132

Copy link
Copy Markdown
Member

For future reference, please create a separate branch for pull requests and don't use main.

@FlexKleks

FlexKleks commented Jan 3, 2026 via email

Copy link
Copy Markdown
ContributorAuthor

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@FlexKleks@Boy132
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

update: Add custom domain support with automatic fallback validation - #73

Merged
Boy132 merged 2 commits into
pelican:mainfrom
FlexKleks:main
Jan 3, 2026
Merged

update: Add custom domain support with automatic fallback validation#73
Boy132 merged 2 commits into
pelican:mainfrom
FlexKleks:main

Conversation

@FlexKleks

@FlexKleksFlexKleks commented Jan 3, 2026

Copy link
Copy Markdown
Contributor

Hey, here's a change to my “PasteFox Share” plugin.

Changes

  • Add custom domain support for paste URLs
  • Add automatic API key validation (falls back to anonymous upload if key is invalid/expired)
  • Add automatic custom domain validation (falls back to pastefox.com if domain is inactive/removed)
  • Add translations for all settings page strings
  • Bump version to 1.1.0

Custom Domains

Users can now select a verified custom domain from their PasteFox account to use for paste URLs. The plugin automatically validates that the domain is still active before using it.

Fallback Behavior

If the configured API key or custom domain becomes unavailable, the plugin gracefully falls back to:

  • Anonymous uploads (7-day expiration, public visibility)
  • Default pastefox.com domain

Summary by CodeRabbit

  • New Features

    • Added Custom Domain support to share pastes from your own verified domain.
    • Domain selection now available in plugin settings (requires API key); verified domains shown, inactive ones disabled.
    • Automatic fallback to pastefox.com if a custom domain is unavailable.
  • Chores

    • Updated plugin version to 1.1.0.
    • Added translations and UI text for custom domain management.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitaiBot commented Jan 3, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds Custom Domain support to PasteFox Share: new config key, translations, README updates, plugin version bump, settings UI to fetch/choose verified domains via API, persistence of selection, and upload logic that validates API key and uses the custom domain or falls back to pastefox.com.

Changes

Cohort / File(s)Summary
Documentation & Manifest
pastefox-share/README.md, pastefox-share/plugin.json
README updated with Custom Domain docs; plugin version bumped from 1.0.01.1.0.
Configuration
pastefox-share/config/pastefox-share.php
New config entry: 'custom_domain' => env('PASTEFOX_CUSTOM_DOMAIN').
Translations
pastefox-share/lang/en/messages.php
Adds translation keys for Custom Domain UI and related helper/error texts (section_custom_domain, custom_domain, custom_domain_none, custom_domain_helper, custom_domain_no_api_key, custom_domain_fetch_error, custom_domain_inactive, etc.).
Settings UI & API integration
pastefox-share/src/PasteFoxSharePlugin.php
Adds HTTP client usage and getCustomDomainOptions() to fetch domains from https://pastefox.com/api/domains; settings form extended with a Select for custom_domain; saveSettings() persists choice to PASTEFOX_CUSTOM_DOMAIN.
Upload logic / Validation
pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php
Adds isApiKeyValid() and getActiveCustomDomain(); upload flow now conditionally includes X-API-Key and uses validated custom domain as base URL or falls back to https://pastefox.com; error handling and conditional payload/header logic added.

Sequence Diagrams

sequenceDiagram
participant User
participant Settings as Plugin Settings
participant API as PasteFox API
participant Env as Environment
participant Upload as UploadLogsAction
User->>Settings: Open settings
Settings->>API: GET /api/domains (X-API-Key if present)
API-->>Settings: Domain list (active/inactive)
Settings->>User: Render domain select (inactive → disabled)
User->>Settings: Select domain & Save
Settings->>Env: Persist PASTEFOX_CUSTOM_DOMAIN
Note over User,Upload: Later — user triggers paste upload
User->>Upload: Trigger upload
Upload->>Env: Read api_key & custom_domain
Upload->>API: Validate API key (isApiKeyValid)
Upload->>API: Verify configured domain (getActiveCustomDomain)
alt custom domain valid
Upload->>API: Create paste using custom domain (X-API-Key header)
else fallback
Upload->>API: Create paste at pastefox.com (no X-API-Key)
end
API-->>Upload: Returns paste URL
Upload-->>User: Show paste URL
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Add PasteFox Share plugin #63: Original PasteFox Share plugin introduction; modifies the same files/classes extended here (UploadLogsAction, PasteFoxSharePlugin, config, translations, manifest).

Suggested reviewers

  • lajczi
  • rmartinoscar

Poem

🐰 I sniffed the code, a domain to share,
Hopped through settings with API flair,
Verified names in dropdown air,
Fallback ready, so no despair,
Logs land safely — hop, share, and care!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 16.67% which is insufficient. The required threshold is 80.00%.You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main feature being added: custom domain support with automatic fallback validation, which aligns with all the changes across configuration, UI, translations, and logic.
✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php (2)

149-168: Consider caching API key validation results.

Every log upload triggers an HTTP request to validate the API key. For frequently accessed servers, this creates unnecessary load and latency. API keys rarely change, making them good candidates for caching.

Consider using Laravel's cache to store validation results for a reasonable TTL (e.g., 5-10 minutes):

protectedfunctionisApiKeyValid(?string$apiKey): bool
{
if (blank($apiKey)) {
returnfalse;
}
$cacheKey = 'pastefox_api_key_valid_' . hash('sha256', $apiKey);
returncache()->remember($cacheKey, 300, function () use ($apiKey) {
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
'Content-Type' => 'application/json',
])
->timeout(5)
->get('https://pastefox.com/api/domains')
->json();
return$response['success'] ?? false;
} catch (\Exception$e) {
returnfalse;
}
});
}

Note: If you implement the consolidated API call from the previous comment, apply caching to the consolidated method instead.


118-147: Silent failure in domain validation could hide configuration issues.

While graceful fallback is appropriate for availability issues, completely silent failure makes it difficult for administrators to diagnose why their custom domain isn't working (e.g., typo in domain name, domain not activated, API connectivity issues).

Consider logging a warning when the configured domain is invalid or inactive:

protectedfunctiongetActiveCustomDomain(?string$apiKey): ?string
{
$configuredDomain = config('pastefox-share.custom_domain');
if (blank($configuredDomain) || blank($apiKey)) {
returnnull;
}
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
'Content-Type' => 'application/json',
])
->timeout(5)
->get('https://pastefox.com/api/domains')
->json();
if ($response['success'] ?? false) {
foreach ($response['domains'] ?? [] as$domain) {
if ($domain['domain'] === $configuredDomain && ($domain['isActive'] ?? false)) {
return$configuredDomain;
}
}
+ // Domain configured but not found or inactive
+ logger()->warning("PasteFox custom domain '{$configuredDomain}' is not active, falling back to pastefox.com");
}
} catch (\Exception$e) {
- // Silently fail, fall back to default
+ logger()->warning("Failed to fetch PasteFox domains: {$e->getMessage()}");
}
returnnull;
}

This helps administrators identify configuration issues while maintaining the graceful fallback behavior.

pastefox-share/src/PasteFoxSharePlugin.php (1)

104-140: Add PHPDoc return type annotation to satisfy PHPStan.

The static analysis error indicates the return type lacks a value type specification. Additionally, the Content-Type header is unnecessary for GET requests.

🔎 Proposed fix
+ /**+ * @return array<string, string>+ */
protected function getCustomDomainOptions(): array
{
$options = ['' => trans('pastefox-share::messages.custom_domain_none')];
$apiKey = config('pastefox-share.api_key');
if (blank($apiKey)) {
return $options;
}
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
- 'Content-Type' => 'application/json',
])
->timeout(10)
->get('https://pastefox.com/api/domains')
->json();
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c2ca0f6 and e53dece.

📒 Files selected for processing (6)
  • pastefox-share/README.md
  • pastefox-share/config/pastefox-share.php
  • pastefox-share/lang/en/messages.php
  • pastefox-share/plugin.json
  • pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php
  • pastefox-share/src/PasteFoxSharePlugin.php
🧰 Additional context used
🪛 GitHub Check: PHPStan
pastefox-share/src/PasteFoxSharePlugin.php

[failure] 104-104:
Method FlexKleks\PasteFoxShare\PasteFoxSharePlugin::getCustomDomainOptions() return type has no value type specified in iterable type array.

🪛 markdownlint-cli2 (0.18.1)
pastefox-share/README.md

24-24: Bare URL used

(MD034, no-bare-urls)

🔇 Additional comments (7)
pastefox-share/plugin.json (1)

5-5: LGTM! Appropriate version bump.

The version increment to 1.1.0 correctly reflects the addition of custom domain support as a new feature.

pastefox-share/config/pastefox-share.php (1)

9-9: LGTM! Configuration entry follows established patterns.

The custom domain configuration is consistent with other optional settings in the file.

pastefox-share/lang/en/messages.php (1)

40-49: LGTM! Comprehensive translation coverage.

The translation keys are well-structured and provide clear, user-friendly messaging for the custom domain feature.

pastefox-share/README.md (2)

22-29: LGTM! Clear configuration documentation.

The updated settings table clearly documents all available configuration options including the new custom domain feature.


38-50: LGTM! Comprehensive custom domain documentation.

The documentation clearly explains:

  • How to set up custom domains
  • The verification process
  • Automatic fallback behavior

This provides users with the information needed to configure and use the feature.

pastefox-share/src/PasteFoxSharePlugin.php (2)

87-100: Well-structured conditional UI behavior.

The custom domain section properly gates functionality based on API key presence—disabling the select and showing appropriate helper text when no API key is configured. The disableOptionWhen pattern using the :disabled suffix cleanly prevents selection of inactive domains while still showing them in the dropdown.


150-150: LGTM!

Persistence of the new setting follows the established pattern. Per the AI summary, runtime validation in UploadLogsAction handles fallback when a configured domain becomes inactive.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
pastefox-share/src/PasteFoxSharePlugin.php (2)

138-140: Consider logging errors while maintaining graceful fallback.

Silent error handling prevents debugging issues with the API integration. Consider logging the exception while still returning default options for graceful degradation.

💡 Suggested refactor to add logging
 } catch (\Exception $e) {
- // Silently fail, just return default options+ \Log::warning('Failed to fetch custom domains from PasteFox API', [+ 'error' => $e->getMessage(),+ ]);
}

122-122: Consider extracting the API URL to a constant or config.

Hardcoding the API URL makes it harder to test or support different environments (staging, local development, etc.).

💡 Suggested refactor

Add to your config file:

'api_base_url' => env('PASTEFOX_API_URL', 'https://pastefox.com'),

Then update the code:

- ->get('https://pastefox.com/api/domains')+ ->get(config('pastefox-share.api_base_url') . '/api/domains')
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e53dece and d762559.

📒 Files selected for processing (1)
  • pastefox-share/src/PasteFoxSharePlugin.php
🔇 Additional comments (3)
pastefox-share/src/PasteFoxSharePlugin.php (3)

13-13: LGTM!

The Http facade import is correctly added to support the API call in getCustomDomainOptions().


153-153: LGTM!

The persistence of the custom domain setting follows the established pattern and is correctly implemented.


127-136: The logic is not inconsistent. The status field validates that the domain is registered in the PasteFox system (status === 'ACTIVE'), while isActive represents the user's preference to enable or disable the domain in their dashboard settings. These are complementary validation layers—one system-level, one user-level—not redundant checks.

Additionally, the :disabled suffix pattern is the proper Filament framework convention. Line 94 shows ->disableOptionWhen(fn (string $value): bool => str_ends_with($value, ':disabled')), which is the intended API for presenting disabled options in the select field. This is not a data/UI mixing issue but correct framework integration.

Likely an incorrect or invalid review comment.

Comment threadpastefox-share/src/PasteFoxSharePlugin.php
@Boy132
Boy132 merged commit 39f9c1f into pelican:mainJan 3, 2026
4 checks passed
@Boy132

Copy link
Copy Markdown
Member

For future reference, please create a separate branch for pull requests and don't use main.

@FlexKleks

FlexKleks commented Jan 3, 2026 via email

Copy link
Copy Markdown
ContributorAuthor

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@FlexKleks@Boy132
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

update: Add custom domain support with automatic fallback validation - #73

Merged
Boy132 merged 2 commits into
pelican:mainfrom
FlexKleks:main
Jan 3, 2026
Merged

update: Add custom domain support with automatic fallback validation#73
Boy132 merged 2 commits into
pelican:mainfrom
FlexKleks:main

Conversation

@FlexKleks

@FlexKleksFlexKleks commented Jan 3, 2026

Copy link
Copy Markdown
Contributor

Hey, here's a change to my “PasteFox Share” plugin.

Changes

  • Add custom domain support for paste URLs
  • Add automatic API key validation (falls back to anonymous upload if key is invalid/expired)
  • Add automatic custom domain validation (falls back to pastefox.com if domain is inactive/removed)
  • Add translations for all settings page strings
  • Bump version to 1.1.0

Custom Domains

Users can now select a verified custom domain from their PasteFox account to use for paste URLs. The plugin automatically validates that the domain is still active before using it.

Fallback Behavior

If the configured API key or custom domain becomes unavailable, the plugin gracefully falls back to:

  • Anonymous uploads (7-day expiration, public visibility)
  • Default pastefox.com domain

Summary by CodeRabbit

  • New Features

    • Added Custom Domain support to share pastes from your own verified domain.
    • Domain selection now available in plugin settings (requires API key); verified domains shown, inactive ones disabled.
    • Automatic fallback to pastefox.com if a custom domain is unavailable.
  • Chores

    • Updated plugin version to 1.1.0.
    • Added translations and UI text for custom domain management.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitaiBot commented Jan 3, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds Custom Domain support to PasteFox Share: new config key, translations, README updates, plugin version bump, settings UI to fetch/choose verified domains via API, persistence of selection, and upload logic that validates API key and uses the custom domain or falls back to pastefox.com.

Changes

Cohort / File(s)Summary
Documentation & Manifest
pastefox-share/README.md, pastefox-share/plugin.json
README updated with Custom Domain docs; plugin version bumped from 1.0.01.1.0.
Configuration
pastefox-share/config/pastefox-share.php
New config entry: 'custom_domain' => env('PASTEFOX_CUSTOM_DOMAIN').
Translations
pastefox-share/lang/en/messages.php
Adds translation keys for Custom Domain UI and related helper/error texts (section_custom_domain, custom_domain, custom_domain_none, custom_domain_helper, custom_domain_no_api_key, custom_domain_fetch_error, custom_domain_inactive, etc.).
Settings UI & API integration
pastefox-share/src/PasteFoxSharePlugin.php
Adds HTTP client usage and getCustomDomainOptions() to fetch domains from https://pastefox.com/api/domains; settings form extended with a Select for custom_domain; saveSettings() persists choice to PASTEFOX_CUSTOM_DOMAIN.
Upload logic / Validation
pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php
Adds isApiKeyValid() and getActiveCustomDomain(); upload flow now conditionally includes X-API-Key and uses validated custom domain as base URL or falls back to https://pastefox.com; error handling and conditional payload/header logic added.

Sequence Diagrams

sequenceDiagram
participant User
participant Settings as Plugin Settings
participant API as PasteFox API
participant Env as Environment
participant Upload as UploadLogsAction
User->>Settings: Open settings
Settings->>API: GET /api/domains (X-API-Key if present)
API-->>Settings: Domain list (active/inactive)
Settings->>User: Render domain select (inactive → disabled)
User->>Settings: Select domain & Save
Settings->>Env: Persist PASTEFOX_CUSTOM_DOMAIN
Note over User,Upload: Later — user triggers paste upload
User->>Upload: Trigger upload
Upload->>Env: Read api_key & custom_domain
Upload->>API: Validate API key (isApiKeyValid)
Upload->>API: Verify configured domain (getActiveCustomDomain)
alt custom domain valid
Upload->>API: Create paste using custom domain (X-API-Key header)
else fallback
Upload->>API: Create paste at pastefox.com (no X-API-Key)
end
API-->>Upload: Returns paste URL
Upload-->>User: Show paste URL
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Add PasteFox Share plugin #63: Original PasteFox Share plugin introduction; modifies the same files/classes extended here (UploadLogsAction, PasteFoxSharePlugin, config, translations, manifest).

Suggested reviewers

  • lajczi
  • rmartinoscar

Poem

🐰 I sniffed the code, a domain to share,
Hopped through settings with API flair,
Verified names in dropdown air,
Fallback ready, so no despair,
Logs land safely — hop, share, and care!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 16.67% which is insufficient. The required threshold is 80.00%.You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main feature being added: custom domain support with automatic fallback validation, which aligns with all the changes across configuration, UI, translations, and logic.
✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php (2)

149-168: Consider caching API key validation results.

Every log upload triggers an HTTP request to validate the API key. For frequently accessed servers, this creates unnecessary load and latency. API keys rarely change, making them good candidates for caching.

Consider using Laravel's cache to store validation results for a reasonable TTL (e.g., 5-10 minutes):

protectedfunctionisApiKeyValid(?string$apiKey): bool
{
if (blank($apiKey)) {
returnfalse;
}
$cacheKey = 'pastefox_api_key_valid_' . hash('sha256', $apiKey);
returncache()->remember($cacheKey, 300, function () use ($apiKey) {
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
'Content-Type' => 'application/json',
])
->timeout(5)
->get('https://pastefox.com/api/domains')
->json();
return$response['success'] ?? false;
} catch (\Exception$e) {
returnfalse;
}
});
}

Note: If you implement the consolidated API call from the previous comment, apply caching to the consolidated method instead.


118-147: Silent failure in domain validation could hide configuration issues.

While graceful fallback is appropriate for availability issues, completely silent failure makes it difficult for administrators to diagnose why their custom domain isn't working (e.g., typo in domain name, domain not activated, API connectivity issues).

Consider logging a warning when the configured domain is invalid or inactive:

protectedfunctiongetActiveCustomDomain(?string$apiKey): ?string
{
$configuredDomain = config('pastefox-share.custom_domain');
if (blank($configuredDomain) || blank($apiKey)) {
returnnull;
}
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
'Content-Type' => 'application/json',
])
->timeout(5)
->get('https://pastefox.com/api/domains')
->json();
if ($response['success'] ?? false) {
foreach ($response['domains'] ?? [] as$domain) {
if ($domain['domain'] === $configuredDomain && ($domain['isActive'] ?? false)) {
return$configuredDomain;
}
}
+ // Domain configured but not found or inactive
+ logger()->warning("PasteFox custom domain '{$configuredDomain}' is not active, falling back to pastefox.com");
}
} catch (\Exception$e) {
- // Silently fail, fall back to default
+ logger()->warning("Failed to fetch PasteFox domains: {$e->getMessage()}");
}
returnnull;
}

This helps administrators identify configuration issues while maintaining the graceful fallback behavior.

pastefox-share/src/PasteFoxSharePlugin.php (1)

104-140: Add PHPDoc return type annotation to satisfy PHPStan.

The static analysis error indicates the return type lacks a value type specification. Additionally, the Content-Type header is unnecessary for GET requests.

🔎 Proposed fix
+ /**+ * @return array<string, string>+ */
protected function getCustomDomainOptions(): array
{
$options = ['' => trans('pastefox-share::messages.custom_domain_none')];
$apiKey = config('pastefox-share.api_key');
if (blank($apiKey)) {
return $options;
}
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
- 'Content-Type' => 'application/json',
])
->timeout(10)
->get('https://pastefox.com/api/domains')
->json();
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c2ca0f6 and e53dece.

📒 Files selected for processing (6)
  • pastefox-share/README.md
  • pastefox-share/config/pastefox-share.php
  • pastefox-share/lang/en/messages.php
  • pastefox-share/plugin.json
  • pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php
  • pastefox-share/src/PasteFoxSharePlugin.php
🧰 Additional context used
🪛 GitHub Check: PHPStan
pastefox-share/src/PasteFoxSharePlugin.php

[failure] 104-104:
Method FlexKleks\PasteFoxShare\PasteFoxSharePlugin::getCustomDomainOptions() return type has no value type specified in iterable type array.

🪛 markdownlint-cli2 (0.18.1)
pastefox-share/README.md

24-24: Bare URL used

(MD034, no-bare-urls)

🔇 Additional comments (7)
pastefox-share/plugin.json (1)

5-5: LGTM! Appropriate version bump.

The version increment to 1.1.0 correctly reflects the addition of custom domain support as a new feature.

pastefox-share/config/pastefox-share.php (1)

9-9: LGTM! Configuration entry follows established patterns.

The custom domain configuration is consistent with other optional settings in the file.

pastefox-share/lang/en/messages.php (1)

40-49: LGTM! Comprehensive translation coverage.

The translation keys are well-structured and provide clear, user-friendly messaging for the custom domain feature.

pastefox-share/README.md (2)

22-29: LGTM! Clear configuration documentation.

The updated settings table clearly documents all available configuration options including the new custom domain feature.


38-50: LGTM! Comprehensive custom domain documentation.

The documentation clearly explains:

  • How to set up custom domains
  • The verification process
  • Automatic fallback behavior

This provides users with the information needed to configure and use the feature.

pastefox-share/src/PasteFoxSharePlugin.php (2)

87-100: Well-structured conditional UI behavior.

The custom domain section properly gates functionality based on API key presence—disabling the select and showing appropriate helper text when no API key is configured. The disableOptionWhen pattern using the :disabled suffix cleanly prevents selection of inactive domains while still showing them in the dropdown.


150-150: LGTM!

Persistence of the new setting follows the established pattern. Per the AI summary, runtime validation in UploadLogsAction handles fallback when a configured domain becomes inactive.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
pastefox-share/src/PasteFoxSharePlugin.php (2)

138-140: Consider logging errors while maintaining graceful fallback.

Silent error handling prevents debugging issues with the API integration. Consider logging the exception while still returning default options for graceful degradation.

💡 Suggested refactor to add logging
 } catch (\Exception $e) {
- // Silently fail, just return default options+ \Log::warning('Failed to fetch custom domains from PasteFox API', [+ 'error' => $e->getMessage(),+ ]);
}

122-122: Consider extracting the API URL to a constant or config.

Hardcoding the API URL makes it harder to test or support different environments (staging, local development, etc.).

💡 Suggested refactor

Add to your config file:

'api_base_url' => env('PASTEFOX_API_URL', 'https://pastefox.com'),

Then update the code:

- ->get('https://pastefox.com/api/domains')+ ->get(config('pastefox-share.api_base_url') . '/api/domains')
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e53dece and d762559.

📒 Files selected for processing (1)
  • pastefox-share/src/PasteFoxSharePlugin.php
🔇 Additional comments (3)
pastefox-share/src/PasteFoxSharePlugin.php (3)

13-13: LGTM!

The Http facade import is correctly added to support the API call in getCustomDomainOptions().


153-153: LGTM!

The persistence of the custom domain setting follows the established pattern and is correctly implemented.


127-136: The logic is not inconsistent. The status field validates that the domain is registered in the PasteFox system (status === 'ACTIVE'), while isActive represents the user's preference to enable or disable the domain in their dashboard settings. These are complementary validation layers—one system-level, one user-level—not redundant checks.

Additionally, the :disabled suffix pattern is the proper Filament framework convention. Line 94 shows ->disableOptionWhen(fn (string $value): bool => str_ends_with($value, ':disabled')), which is the intended API for presenting disabled options in the select field. This is not a data/UI mixing issue but correct framework integration.

Likely an incorrect or invalid review comment.

Comment threadpastefox-share/src/PasteFoxSharePlugin.php
@Boy132
Boy132 merged commit 39f9c1f into pelican:mainJan 3, 2026
4 checks passed
@Boy132

Copy link
Copy Markdown
Member

For future reference, please create a separate branch for pull requests and don't use main.

@FlexKleks

FlexKleks commented Jan 3, 2026 via email

Copy link
Copy Markdown
ContributorAuthor

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@FlexKleks@Boy132
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

update: Add custom domain support with automatic fallback validation - #73

Merged
Boy132 merged 2 commits into
pelican:mainfrom
FlexKleks:main
Jan 3, 2026
Merged

update: Add custom domain support with automatic fallback validation#73
Boy132 merged 2 commits into
pelican:mainfrom
FlexKleks:main

Conversation

@FlexKleks

@FlexKleksFlexKleks commented Jan 3, 2026

Copy link
Copy Markdown
Contributor

Hey, here's a change to my “PasteFox Share” plugin.

Changes

  • Add custom domain support for paste URLs
  • Add automatic API key validation (falls back to anonymous upload if key is invalid/expired)
  • Add automatic custom domain validation (falls back to pastefox.com if domain is inactive/removed)
  • Add translations for all settings page strings
  • Bump version to 1.1.0

Custom Domains

Users can now select a verified custom domain from their PasteFox account to use for paste URLs. The plugin automatically validates that the domain is still active before using it.

Fallback Behavior

If the configured API key or custom domain becomes unavailable, the plugin gracefully falls back to:

  • Anonymous uploads (7-day expiration, public visibility)
  • Default pastefox.com domain

Summary by CodeRabbit

  • New Features

    • Added Custom Domain support to share pastes from your own verified domain.
    • Domain selection now available in plugin settings (requires API key); verified domains shown, inactive ones disabled.
    • Automatic fallback to pastefox.com if a custom domain is unavailable.
  • Chores

    • Updated plugin version to 1.1.0.
    • Added translations and UI text for custom domain management.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitaiBot commented Jan 3, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds Custom Domain support to PasteFox Share: new config key, translations, README updates, plugin version bump, settings UI to fetch/choose verified domains via API, persistence of selection, and upload logic that validates API key and uses the custom domain or falls back to pastefox.com.

Changes

Cohort / File(s)Summary
Documentation & Manifest
pastefox-share/README.md, pastefox-share/plugin.json
README updated with Custom Domain docs; plugin version bumped from 1.0.01.1.0.
Configuration
pastefox-share/config/pastefox-share.php
New config entry: 'custom_domain' => env('PASTEFOX_CUSTOM_DOMAIN').
Translations
pastefox-share/lang/en/messages.php
Adds translation keys for Custom Domain UI and related helper/error texts (section_custom_domain, custom_domain, custom_domain_none, custom_domain_helper, custom_domain_no_api_key, custom_domain_fetch_error, custom_domain_inactive, etc.).
Settings UI & API integration
pastefox-share/src/PasteFoxSharePlugin.php
Adds HTTP client usage and getCustomDomainOptions() to fetch domains from https://pastefox.com/api/domains; settings form extended with a Select for custom_domain; saveSettings() persists choice to PASTEFOX_CUSTOM_DOMAIN.
Upload logic / Validation
pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php
Adds isApiKeyValid() and getActiveCustomDomain(); upload flow now conditionally includes X-API-Key and uses validated custom domain as base URL or falls back to https://pastefox.com; error handling and conditional payload/header logic added.

Sequence Diagrams

sequenceDiagram
participant User
participant Settings as Plugin Settings
participant API as PasteFox API
participant Env as Environment
participant Upload as UploadLogsAction
User->>Settings: Open settings
Settings->>API: GET /api/domains (X-API-Key if present)
API-->>Settings: Domain list (active/inactive)
Settings->>User: Render domain select (inactive → disabled)
User->>Settings: Select domain & Save
Settings->>Env: Persist PASTEFOX_CUSTOM_DOMAIN
Note over User,Upload: Later — user triggers paste upload
User->>Upload: Trigger upload
Upload->>Env: Read api_key & custom_domain
Upload->>API: Validate API key (isApiKeyValid)
Upload->>API: Verify configured domain (getActiveCustomDomain)
alt custom domain valid
Upload->>API: Create paste using custom domain (X-API-Key header)
else fallback
Upload->>API: Create paste at pastefox.com (no X-API-Key)
end
API-->>Upload: Returns paste URL
Upload-->>User: Show paste URL
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Add PasteFox Share plugin #63: Original PasteFox Share plugin introduction; modifies the same files/classes extended here (UploadLogsAction, PasteFoxSharePlugin, config, translations, manifest).

Suggested reviewers

  • lajczi
  • rmartinoscar

Poem

🐰 I sniffed the code, a domain to share,
Hopped through settings with API flair,
Verified names in dropdown air,
Fallback ready, so no despair,
Logs land safely — hop, share, and care!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 16.67% which is insufficient. The required threshold is 80.00%.You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main feature being added: custom domain support with automatic fallback validation, which aligns with all the changes across configuration, UI, translations, and logic.
✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php (2)

149-168: Consider caching API key validation results.

Every log upload triggers an HTTP request to validate the API key. For frequently accessed servers, this creates unnecessary load and latency. API keys rarely change, making them good candidates for caching.

Consider using Laravel's cache to store validation results for a reasonable TTL (e.g., 5-10 minutes):

protectedfunctionisApiKeyValid(?string$apiKey): bool
{
if (blank($apiKey)) {
returnfalse;
}
$cacheKey = 'pastefox_api_key_valid_' . hash('sha256', $apiKey);
returncache()->remember($cacheKey, 300, function () use ($apiKey) {
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
'Content-Type' => 'application/json',
])
->timeout(5)
->get('https://pastefox.com/api/domains')
->json();
return$response['success'] ?? false;
} catch (\Exception$e) {
returnfalse;
}
});
}

Note: If you implement the consolidated API call from the previous comment, apply caching to the consolidated method instead.


118-147: Silent failure in domain validation could hide configuration issues.

While graceful fallback is appropriate for availability issues, completely silent failure makes it difficult for administrators to diagnose why their custom domain isn't working (e.g., typo in domain name, domain not activated, API connectivity issues).

Consider logging a warning when the configured domain is invalid or inactive:

protectedfunctiongetActiveCustomDomain(?string$apiKey): ?string
{
$configuredDomain = config('pastefox-share.custom_domain');
if (blank($configuredDomain) || blank($apiKey)) {
returnnull;
}
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
'Content-Type' => 'application/json',
])
->timeout(5)
->get('https://pastefox.com/api/domains')
->json();
if ($response['success'] ?? false) {
foreach ($response['domains'] ?? [] as$domain) {
if ($domain['domain'] === $configuredDomain && ($domain['isActive'] ?? false)) {
return$configuredDomain;
}
}
+ // Domain configured but not found or inactive
+ logger()->warning("PasteFox custom domain '{$configuredDomain}' is not active, falling back to pastefox.com");
}
} catch (\Exception$e) {
- // Silently fail, fall back to default
+ logger()->warning("Failed to fetch PasteFox domains: {$e->getMessage()}");
}
returnnull;
}

This helps administrators identify configuration issues while maintaining the graceful fallback behavior.

pastefox-share/src/PasteFoxSharePlugin.php (1)

104-140: Add PHPDoc return type annotation to satisfy PHPStan.

The static analysis error indicates the return type lacks a value type specification. Additionally, the Content-Type header is unnecessary for GET requests.

🔎 Proposed fix
+ /**+ * @return array<string, string>+ */
protected function getCustomDomainOptions(): array
{
$options = ['' => trans('pastefox-share::messages.custom_domain_none')];
$apiKey = config('pastefox-share.api_key');
if (blank($apiKey)) {
return $options;
}
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
- 'Content-Type' => 'application/json',
])
->timeout(10)
->get('https://pastefox.com/api/domains')
->json();
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c2ca0f6 and e53dece.

📒 Files selected for processing (6)
  • pastefox-share/README.md
  • pastefox-share/config/pastefox-share.php
  • pastefox-share/lang/en/messages.php
  • pastefox-share/plugin.json
  • pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php
  • pastefox-share/src/PasteFoxSharePlugin.php
🧰 Additional context used
🪛 GitHub Check: PHPStan
pastefox-share/src/PasteFoxSharePlugin.php

[failure] 104-104:
Method FlexKleks\PasteFoxShare\PasteFoxSharePlugin::getCustomDomainOptions() return type has no value type specified in iterable type array.

🪛 markdownlint-cli2 (0.18.1)
pastefox-share/README.md

24-24: Bare URL used

(MD034, no-bare-urls)

🔇 Additional comments (7)
pastefox-share/plugin.json (1)

5-5: LGTM! Appropriate version bump.

The version increment to 1.1.0 correctly reflects the addition of custom domain support as a new feature.

pastefox-share/config/pastefox-share.php (1)

9-9: LGTM! Configuration entry follows established patterns.

The custom domain configuration is consistent with other optional settings in the file.

pastefox-share/lang/en/messages.php (1)

40-49: LGTM! Comprehensive translation coverage.

The translation keys are well-structured and provide clear, user-friendly messaging for the custom domain feature.

pastefox-share/README.md (2)

22-29: LGTM! Clear configuration documentation.

The updated settings table clearly documents all available configuration options including the new custom domain feature.


38-50: LGTM! Comprehensive custom domain documentation.

The documentation clearly explains:

  • How to set up custom domains
  • The verification process
  • Automatic fallback behavior

This provides users with the information needed to configure and use the feature.

pastefox-share/src/PasteFoxSharePlugin.php (2)

87-100: Well-structured conditional UI behavior.

The custom domain section properly gates functionality based on API key presence—disabling the select and showing appropriate helper text when no API key is configured. The disableOptionWhen pattern using the :disabled suffix cleanly prevents selection of inactive domains while still showing them in the dropdown.


150-150: LGTM!

Persistence of the new setting follows the established pattern. Per the AI summary, runtime validation in UploadLogsAction handles fallback when a configured domain becomes inactive.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
pastefox-share/src/PasteFoxSharePlugin.php (2)

138-140: Consider logging errors while maintaining graceful fallback.

Silent error handling prevents debugging issues with the API integration. Consider logging the exception while still returning default options for graceful degradation.

💡 Suggested refactor to add logging
 } catch (\Exception $e) {
- // Silently fail, just return default options+ \Log::warning('Failed to fetch custom domains from PasteFox API', [+ 'error' => $e->getMessage(),+ ]);
}

122-122: Consider extracting the API URL to a constant or config.

Hardcoding the API URL makes it harder to test or support different environments (staging, local development, etc.).

💡 Suggested refactor

Add to your config file:

'api_base_url' => env('PASTEFOX_API_URL', 'https://pastefox.com'),

Then update the code:

- ->get('https://pastefox.com/api/domains')+ ->get(config('pastefox-share.api_base_url') . '/api/domains')
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e53dece and d762559.

📒 Files selected for processing (1)
  • pastefox-share/src/PasteFoxSharePlugin.php
🔇 Additional comments (3)
pastefox-share/src/PasteFoxSharePlugin.php (3)

13-13: LGTM!

The Http facade import is correctly added to support the API call in getCustomDomainOptions().


153-153: LGTM!

The persistence of the custom domain setting follows the established pattern and is correctly implemented.


127-136: The logic is not inconsistent. The status field validates that the domain is registered in the PasteFox system (status === 'ACTIVE'), while isActive represents the user's preference to enable or disable the domain in their dashboard settings. These are complementary validation layers—one system-level, one user-level—not redundant checks.

Additionally, the :disabled suffix pattern is the proper Filament framework convention. Line 94 shows ->disableOptionWhen(fn (string $value): bool => str_ends_with($value, ':disabled')), which is the intended API for presenting disabled options in the select field. This is not a data/UI mixing issue but correct framework integration.

Likely an incorrect or invalid review comment.

Comment threadpastefox-share/src/PasteFoxSharePlugin.php
@Boy132
Boy132 merged commit 39f9c1f into pelican:mainJan 3, 2026
4 checks passed
@Boy132

Copy link
Copy Markdown
Member

For future reference, please create a separate branch for pull requests and don't use main.

@FlexKleks

FlexKleks commented Jan 3, 2026 via email

Copy link
Copy Markdown
ContributorAuthor

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@FlexKleks@Boy132
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

update: Add custom domain support with automatic fallback validation - #73

Merged
Boy132 merged 2 commits into
pelican:mainfrom
FlexKleks:main
Jan 3, 2026
Merged

update: Add custom domain support with automatic fallback validation#73
Boy132 merged 2 commits into
pelican:mainfrom
FlexKleks:main

Conversation

@FlexKleks

@FlexKleksFlexKleks commented Jan 3, 2026

Copy link
Copy Markdown
Contributor

Hey, here's a change to my “PasteFox Share” plugin.

Changes

  • Add custom domain support for paste URLs
  • Add automatic API key validation (falls back to anonymous upload if key is invalid/expired)
  • Add automatic custom domain validation (falls back to pastefox.com if domain is inactive/removed)
  • Add translations for all settings page strings
  • Bump version to 1.1.0

Custom Domains

Users can now select a verified custom domain from their PasteFox account to use for paste URLs. The plugin automatically validates that the domain is still active before using it.

Fallback Behavior

If the configured API key or custom domain becomes unavailable, the plugin gracefully falls back to:

  • Anonymous uploads (7-day expiration, public visibility)
  • Default pastefox.com domain

Summary by CodeRabbit

  • New Features

    • Added Custom Domain support to share pastes from your own verified domain.
    • Domain selection now available in plugin settings (requires API key); verified domains shown, inactive ones disabled.
    • Automatic fallback to pastefox.com if a custom domain is unavailable.
  • Chores

    • Updated plugin version to 1.1.0.
    • Added translations and UI text for custom domain management.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitaiBot commented Jan 3, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds Custom Domain support to PasteFox Share: new config key, translations, README updates, plugin version bump, settings UI to fetch/choose verified domains via API, persistence of selection, and upload logic that validates API key and uses the custom domain or falls back to pastefox.com.

Changes

Cohort / File(s)Summary
Documentation & Manifest
pastefox-share/README.md, pastefox-share/plugin.json
README updated with Custom Domain docs; plugin version bumped from 1.0.01.1.0.
Configuration
pastefox-share/config/pastefox-share.php
New config entry: 'custom_domain' => env('PASTEFOX_CUSTOM_DOMAIN').
Translations
pastefox-share/lang/en/messages.php
Adds translation keys for Custom Domain UI and related helper/error texts (section_custom_domain, custom_domain, custom_domain_none, custom_domain_helper, custom_domain_no_api_key, custom_domain_fetch_error, custom_domain_inactive, etc.).
Settings UI & API integration
pastefox-share/src/PasteFoxSharePlugin.php
Adds HTTP client usage and getCustomDomainOptions() to fetch domains from https://pastefox.com/api/domains; settings form extended with a Select for custom_domain; saveSettings() persists choice to PASTEFOX_CUSTOM_DOMAIN.
Upload logic / Validation
pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php
Adds isApiKeyValid() and getActiveCustomDomain(); upload flow now conditionally includes X-API-Key and uses validated custom domain as base URL or falls back to https://pastefox.com; error handling and conditional payload/header logic added.

Sequence Diagrams

sequenceDiagram
participant User
participant Settings as Plugin Settings
participant API as PasteFox API
participant Env as Environment
participant Upload as UploadLogsAction
User->>Settings: Open settings
Settings->>API: GET /api/domains (X-API-Key if present)
API-->>Settings: Domain list (active/inactive)
Settings->>User: Render domain select (inactive → disabled)
User->>Settings: Select domain & Save
Settings->>Env: Persist PASTEFOX_CUSTOM_DOMAIN
Note over User,Upload: Later — user triggers paste upload
User->>Upload: Trigger upload
Upload->>Env: Read api_key & custom_domain
Upload->>API: Validate API key (isApiKeyValid)
Upload->>API: Verify configured domain (getActiveCustomDomain)
alt custom domain valid
Upload->>API: Create paste using custom domain (X-API-Key header)
else fallback
Upload->>API: Create paste at pastefox.com (no X-API-Key)
end
API-->>Upload: Returns paste URL
Upload-->>User: Show paste URL
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Add PasteFox Share plugin #63: Original PasteFox Share plugin introduction; modifies the same files/classes extended here (UploadLogsAction, PasteFoxSharePlugin, config, translations, manifest).

Suggested reviewers

  • lajczi
  • rmartinoscar

Poem

🐰 I sniffed the code, a domain to share,
Hopped through settings with API flair,
Verified names in dropdown air,
Fallback ready, so no despair,
Logs land safely — hop, share, and care!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 16.67% which is insufficient. The required threshold is 80.00%.You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main feature being added: custom domain support with automatic fallback validation, which aligns with all the changes across configuration, UI, translations, and logic.
✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php (2)

149-168: Consider caching API key validation results.

Every log upload triggers an HTTP request to validate the API key. For frequently accessed servers, this creates unnecessary load and latency. API keys rarely change, making them good candidates for caching.

Consider using Laravel's cache to store validation results for a reasonable TTL (e.g., 5-10 minutes):

protectedfunctionisApiKeyValid(?string$apiKey): bool
{
if (blank($apiKey)) {
returnfalse;
}
$cacheKey = 'pastefox_api_key_valid_' . hash('sha256', $apiKey);
returncache()->remember($cacheKey, 300, function () use ($apiKey) {
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
'Content-Type' => 'application/json',
])
->timeout(5)
->get('https://pastefox.com/api/domains')
->json();
return$response['success'] ?? false;
} catch (\Exception$e) {
returnfalse;
}
});
}

Note: If you implement the consolidated API call from the previous comment, apply caching to the consolidated method instead.


118-147: Silent failure in domain validation could hide configuration issues.

While graceful fallback is appropriate for availability issues, completely silent failure makes it difficult for administrators to diagnose why their custom domain isn't working (e.g., typo in domain name, domain not activated, API connectivity issues).

Consider logging a warning when the configured domain is invalid or inactive:

protectedfunctiongetActiveCustomDomain(?string$apiKey): ?string
{
$configuredDomain = config('pastefox-share.custom_domain');
if (blank($configuredDomain) || blank($apiKey)) {
returnnull;
}
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
'Content-Type' => 'application/json',
])
->timeout(5)
->get('https://pastefox.com/api/domains')
->json();
if ($response['success'] ?? false) {
foreach ($response['domains'] ?? [] as$domain) {
if ($domain['domain'] === $configuredDomain && ($domain['isActive'] ?? false)) {
return$configuredDomain;
}
}
+ // Domain configured but not found or inactive
+ logger()->warning("PasteFox custom domain '{$configuredDomain}' is not active, falling back to pastefox.com");
}
} catch (\Exception$e) {
- // Silently fail, fall back to default
+ logger()->warning("Failed to fetch PasteFox domains: {$e->getMessage()}");
}
returnnull;
}

This helps administrators identify configuration issues while maintaining the graceful fallback behavior.

pastefox-share/src/PasteFoxSharePlugin.php (1)

104-140: Add PHPDoc return type annotation to satisfy PHPStan.

The static analysis error indicates the return type lacks a value type specification. Additionally, the Content-Type header is unnecessary for GET requests.

🔎 Proposed fix
+ /**+ * @return array<string, string>+ */
protected function getCustomDomainOptions(): array
{
$options = ['' => trans('pastefox-share::messages.custom_domain_none')];
$apiKey = config('pastefox-share.api_key');
if (blank($apiKey)) {
return $options;
}
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
- 'Content-Type' => 'application/json',
])
->timeout(10)
->get('https://pastefox.com/api/domains')
->json();
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c2ca0f6 and e53dece.

📒 Files selected for processing (6)
  • pastefox-share/README.md
  • pastefox-share/config/pastefox-share.php
  • pastefox-share/lang/en/messages.php
  • pastefox-share/plugin.json
  • pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php
  • pastefox-share/src/PasteFoxSharePlugin.php
🧰 Additional context used
🪛 GitHub Check: PHPStan
pastefox-share/src/PasteFoxSharePlugin.php

[failure] 104-104:
Method FlexKleks\PasteFoxShare\PasteFoxSharePlugin::getCustomDomainOptions() return type has no value type specified in iterable type array.

🪛 markdownlint-cli2 (0.18.1)
pastefox-share/README.md

24-24: Bare URL used

(MD034, no-bare-urls)

🔇 Additional comments (7)
pastefox-share/plugin.json (1)

5-5: LGTM! Appropriate version bump.

The version increment to 1.1.0 correctly reflects the addition of custom domain support as a new feature.

pastefox-share/config/pastefox-share.php (1)

9-9: LGTM! Configuration entry follows established patterns.

The custom domain configuration is consistent with other optional settings in the file.

pastefox-share/lang/en/messages.php (1)

40-49: LGTM! Comprehensive translation coverage.

The translation keys are well-structured and provide clear, user-friendly messaging for the custom domain feature.

pastefox-share/README.md (2)

22-29: LGTM! Clear configuration documentation.

The updated settings table clearly documents all available configuration options including the new custom domain feature.


38-50: LGTM! Comprehensive custom domain documentation.

The documentation clearly explains:

  • How to set up custom domains
  • The verification process
  • Automatic fallback behavior

This provides users with the information needed to configure and use the feature.

pastefox-share/src/PasteFoxSharePlugin.php (2)

87-100: Well-structured conditional UI behavior.

The custom domain section properly gates functionality based on API key presence—disabling the select and showing appropriate helper text when no API key is configured. The disableOptionWhen pattern using the :disabled suffix cleanly prevents selection of inactive domains while still showing them in the dropdown.


150-150: LGTM!

Persistence of the new setting follows the established pattern. Per the AI summary, runtime validation in UploadLogsAction handles fallback when a configured domain becomes inactive.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
pastefox-share/src/PasteFoxSharePlugin.php (2)

138-140: Consider logging errors while maintaining graceful fallback.

Silent error handling prevents debugging issues with the API integration. Consider logging the exception while still returning default options for graceful degradation.

💡 Suggested refactor to add logging
 } catch (\Exception $e) {
- // Silently fail, just return default options+ \Log::warning('Failed to fetch custom domains from PasteFox API', [+ 'error' => $e->getMessage(),+ ]);
}

122-122: Consider extracting the API URL to a constant or config.

Hardcoding the API URL makes it harder to test or support different environments (staging, local development, etc.).

💡 Suggested refactor

Add to your config file:

'api_base_url' => env('PASTEFOX_API_URL', 'https://pastefox.com'),

Then update the code:

- ->get('https://pastefox.com/api/domains')+ ->get(config('pastefox-share.api_base_url') . '/api/domains')
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e53dece and d762559.

📒 Files selected for processing (1)
  • pastefox-share/src/PasteFoxSharePlugin.php
🔇 Additional comments (3)
pastefox-share/src/PasteFoxSharePlugin.php (3)

13-13: LGTM!

The Http facade import is correctly added to support the API call in getCustomDomainOptions().


153-153: LGTM!

The persistence of the custom domain setting follows the established pattern and is correctly implemented.


127-136: The logic is not inconsistent. The status field validates that the domain is registered in the PasteFox system (status === 'ACTIVE'), while isActive represents the user's preference to enable or disable the domain in their dashboard settings. These are complementary validation layers—one system-level, one user-level—not redundant checks.

Additionally, the :disabled suffix pattern is the proper Filament framework convention. Line 94 shows ->disableOptionWhen(fn (string $value): bool => str_ends_with($value, ':disabled')), which is the intended API for presenting disabled options in the select field. This is not a data/UI mixing issue but correct framework integration.

Likely an incorrect or invalid review comment.

Comment threadpastefox-share/src/PasteFoxSharePlugin.php
@Boy132
Boy132 merged commit 39f9c1f into pelican:mainJan 3, 2026
4 checks passed
@Boy132

Copy link
Copy Markdown
Member

For future reference, please create a separate branch for pull requests and don't use main.

@FlexKleks

FlexKleks commented Jan 3, 2026 via email

Copy link
Copy Markdown
ContributorAuthor

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@FlexKleks@Boy132
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

update: Add custom domain support with automatic fallback validation - #73

Merged
Boy132 merged 2 commits into
pelican:mainfrom
FlexKleks:main
Jan 3, 2026
Merged

update: Add custom domain support with automatic fallback validation#73
Boy132 merged 2 commits into
pelican:mainfrom
FlexKleks:main

Conversation

@FlexKleks

@FlexKleksFlexKleks commented Jan 3, 2026

Copy link
Copy Markdown
Contributor

Hey, here's a change to my “PasteFox Share” plugin.

Changes

  • Add custom domain support for paste URLs
  • Add automatic API key validation (falls back to anonymous upload if key is invalid/expired)
  • Add automatic custom domain validation (falls back to pastefox.com if domain is inactive/removed)
  • Add translations for all settings page strings
  • Bump version to 1.1.0

Custom Domains

Users can now select a verified custom domain from their PasteFox account to use for paste URLs. The plugin automatically validates that the domain is still active before using it.

Fallback Behavior

If the configured API key or custom domain becomes unavailable, the plugin gracefully falls back to:

  • Anonymous uploads (7-day expiration, public visibility)
  • Default pastefox.com domain

Summary by CodeRabbit

  • New Features

    • Added Custom Domain support to share pastes from your own verified domain.
    • Domain selection now available in plugin settings (requires API key); verified domains shown, inactive ones disabled.
    • Automatic fallback to pastefox.com if a custom domain is unavailable.
  • Chores

    • Updated plugin version to 1.1.0.
    • Added translations and UI text for custom domain management.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitaiBot commented Jan 3, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds Custom Domain support to PasteFox Share: new config key, translations, README updates, plugin version bump, settings UI to fetch/choose verified domains via API, persistence of selection, and upload logic that validates API key and uses the custom domain or falls back to pastefox.com.

Changes

Cohort / File(s)Summary
Documentation & Manifest
pastefox-share/README.md, pastefox-share/plugin.json
README updated with Custom Domain docs; plugin version bumped from 1.0.01.1.0.
Configuration
pastefox-share/config/pastefox-share.php
New config entry: 'custom_domain' => env('PASTEFOX_CUSTOM_DOMAIN').
Translations
pastefox-share/lang/en/messages.php
Adds translation keys for Custom Domain UI and related helper/error texts (section_custom_domain, custom_domain, custom_domain_none, custom_domain_helper, custom_domain_no_api_key, custom_domain_fetch_error, custom_domain_inactive, etc.).
Settings UI & API integration
pastefox-share/src/PasteFoxSharePlugin.php
Adds HTTP client usage and getCustomDomainOptions() to fetch domains from https://pastefox.com/api/domains; settings form extended with a Select for custom_domain; saveSettings() persists choice to PASTEFOX_CUSTOM_DOMAIN.
Upload logic / Validation
pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php
Adds isApiKeyValid() and getActiveCustomDomain(); upload flow now conditionally includes X-API-Key and uses validated custom domain as base URL or falls back to https://pastefox.com; error handling and conditional payload/header logic added.

Sequence Diagrams

sequenceDiagram
participant User
participant Settings as Plugin Settings
participant API as PasteFox API
participant Env as Environment
participant Upload as UploadLogsAction
User->>Settings: Open settings
Settings->>API: GET /api/domains (X-API-Key if present)
API-->>Settings: Domain list (active/inactive)
Settings->>User: Render domain select (inactive → disabled)
User->>Settings: Select domain & Save
Settings->>Env: Persist PASTEFOX_CUSTOM_DOMAIN
Note over User,Upload: Later — user triggers paste upload
User->>Upload: Trigger upload
Upload->>Env: Read api_key & custom_domain
Upload->>API: Validate API key (isApiKeyValid)
Upload->>API: Verify configured domain (getActiveCustomDomain)
alt custom domain valid
Upload->>API: Create paste using custom domain (X-API-Key header)
else fallback
Upload->>API: Create paste at pastefox.com (no X-API-Key)
end
API-->>Upload: Returns paste URL
Upload-->>User: Show paste URL
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Add PasteFox Share plugin #63: Original PasteFox Share plugin introduction; modifies the same files/classes extended here (UploadLogsAction, PasteFoxSharePlugin, config, translations, manifest).

Suggested reviewers

  • lajczi
  • rmartinoscar

Poem

🐰 I sniffed the code, a domain to share,
Hopped through settings with API flair,
Verified names in dropdown air,
Fallback ready, so no despair,
Logs land safely — hop, share, and care!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 16.67% which is insufficient. The required threshold is 80.00%.You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main feature being added: custom domain support with automatic fallback validation, which aligns with all the changes across configuration, UI, translations, and logic.
✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php (2)

149-168: Consider caching API key validation results.

Every log upload triggers an HTTP request to validate the API key. For frequently accessed servers, this creates unnecessary load and latency. API keys rarely change, making them good candidates for caching.

Consider using Laravel's cache to store validation results for a reasonable TTL (e.g., 5-10 minutes):

protectedfunctionisApiKeyValid(?string$apiKey): bool
{
if (blank($apiKey)) {
returnfalse;
}
$cacheKey = 'pastefox_api_key_valid_' . hash('sha256', $apiKey);
returncache()->remember($cacheKey, 300, function () use ($apiKey) {
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
'Content-Type' => 'application/json',
])
->timeout(5)
->get('https://pastefox.com/api/domains')
->json();
return$response['success'] ?? false;
} catch (\Exception$e) {
returnfalse;
}
});
}

Note: If you implement the consolidated API call from the previous comment, apply caching to the consolidated method instead.


118-147: Silent failure in domain validation could hide configuration issues.

While graceful fallback is appropriate for availability issues, completely silent failure makes it difficult for administrators to diagnose why their custom domain isn't working (e.g., typo in domain name, domain not activated, API connectivity issues).

Consider logging a warning when the configured domain is invalid or inactive:

protectedfunctiongetActiveCustomDomain(?string$apiKey): ?string
{
$configuredDomain = config('pastefox-share.custom_domain');
if (blank($configuredDomain) || blank($apiKey)) {
returnnull;
}
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
'Content-Type' => 'application/json',
])
->timeout(5)
->get('https://pastefox.com/api/domains')
->json();
if ($response['success'] ?? false) {
foreach ($response['domains'] ?? [] as$domain) {
if ($domain['domain'] === $configuredDomain && ($domain['isActive'] ?? false)) {
return$configuredDomain;
}
}
+ // Domain configured but not found or inactive
+ logger()->warning("PasteFox custom domain '{$configuredDomain}' is not active, falling back to pastefox.com");
}
} catch (\Exception$e) {
- // Silently fail, fall back to default
+ logger()->warning("Failed to fetch PasteFox domains: {$e->getMessage()}");
}
returnnull;
}

This helps administrators identify configuration issues while maintaining the graceful fallback behavior.

pastefox-share/src/PasteFoxSharePlugin.php (1)

104-140: Add PHPDoc return type annotation to satisfy PHPStan.

The static analysis error indicates the return type lacks a value type specification. Additionally, the Content-Type header is unnecessary for GET requests.

🔎 Proposed fix
+ /**+ * @return array<string, string>+ */
protected function getCustomDomainOptions(): array
{
$options = ['' => trans('pastefox-share::messages.custom_domain_none')];
$apiKey = config('pastefox-share.api_key');
if (blank($apiKey)) {
return $options;
}
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
- 'Content-Type' => 'application/json',
])
->timeout(10)
->get('https://pastefox.com/api/domains')
->json();
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c2ca0f6 and e53dece.

📒 Files selected for processing (6)
  • pastefox-share/README.md
  • pastefox-share/config/pastefox-share.php
  • pastefox-share/lang/en/messages.php
  • pastefox-share/plugin.json
  • pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php
  • pastefox-share/src/PasteFoxSharePlugin.php
🧰 Additional context used
🪛 GitHub Check: PHPStan
pastefox-share/src/PasteFoxSharePlugin.php

[failure] 104-104:
Method FlexKleks\PasteFoxShare\PasteFoxSharePlugin::getCustomDomainOptions() return type has no value type specified in iterable type array.

🪛 markdownlint-cli2 (0.18.1)
pastefox-share/README.md

24-24: Bare URL used

(MD034, no-bare-urls)

🔇 Additional comments (7)
pastefox-share/plugin.json (1)

5-5: LGTM! Appropriate version bump.

The version increment to 1.1.0 correctly reflects the addition of custom domain support as a new feature.

pastefox-share/config/pastefox-share.php (1)

9-9: LGTM! Configuration entry follows established patterns.

The custom domain configuration is consistent with other optional settings in the file.

pastefox-share/lang/en/messages.php (1)

40-49: LGTM! Comprehensive translation coverage.

The translation keys are well-structured and provide clear, user-friendly messaging for the custom domain feature.

pastefox-share/README.md (2)

22-29: LGTM! Clear configuration documentation.

The updated settings table clearly documents all available configuration options including the new custom domain feature.


38-50: LGTM! Comprehensive custom domain documentation.

The documentation clearly explains:

  • How to set up custom domains
  • The verification process
  • Automatic fallback behavior

This provides users with the information needed to configure and use the feature.

pastefox-share/src/PasteFoxSharePlugin.php (2)

87-100: Well-structured conditional UI behavior.

The custom domain section properly gates functionality based on API key presence—disabling the select and showing appropriate helper text when no API key is configured. The disableOptionWhen pattern using the :disabled suffix cleanly prevents selection of inactive domains while still showing them in the dropdown.


150-150: LGTM!

Persistence of the new setting follows the established pattern. Per the AI summary, runtime validation in UploadLogsAction handles fallback when a configured domain becomes inactive.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
pastefox-share/src/PasteFoxSharePlugin.php (2)

138-140: Consider logging errors while maintaining graceful fallback.

Silent error handling prevents debugging issues with the API integration. Consider logging the exception while still returning default options for graceful degradation.

💡 Suggested refactor to add logging
 } catch (\Exception $e) {
- // Silently fail, just return default options+ \Log::warning('Failed to fetch custom domains from PasteFox API', [+ 'error' => $e->getMessage(),+ ]);
}

122-122: Consider extracting the API URL to a constant or config.

Hardcoding the API URL makes it harder to test or support different environments (staging, local development, etc.).

💡 Suggested refactor

Add to your config file:

'api_base_url' => env('PASTEFOX_API_URL', 'https://pastefox.com'),

Then update the code:

- ->get('https://pastefox.com/api/domains')+ ->get(config('pastefox-share.api_base_url') . '/api/domains')
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e53dece and d762559.

📒 Files selected for processing (1)
  • pastefox-share/src/PasteFoxSharePlugin.php
🔇 Additional comments (3)
pastefox-share/src/PasteFoxSharePlugin.php (3)

13-13: LGTM!

The Http facade import is correctly added to support the API call in getCustomDomainOptions().


153-153: LGTM!

The persistence of the custom domain setting follows the established pattern and is correctly implemented.


127-136: The logic is not inconsistent. The status field validates that the domain is registered in the PasteFox system (status === 'ACTIVE'), while isActive represents the user's preference to enable or disable the domain in their dashboard settings. These are complementary validation layers—one system-level, one user-level—not redundant checks.

Additionally, the :disabled suffix pattern is the proper Filament framework convention. Line 94 shows ->disableOptionWhen(fn (string $value): bool => str_ends_with($value, ':disabled')), which is the intended API for presenting disabled options in the select field. This is not a data/UI mixing issue but correct framework integration.

Likely an incorrect or invalid review comment.

Comment threadpastefox-share/src/PasteFoxSharePlugin.php
@Boy132
Boy132 merged commit 39f9c1f into pelican:mainJan 3, 2026
4 checks passed
@Boy132

Copy link
Copy Markdown
Member

For future reference, please create a separate branch for pull requests and don't use main.

@FlexKleks

FlexKleks commented Jan 3, 2026 via email

Copy link
Copy Markdown
ContributorAuthor

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@FlexKleks@Boy132
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

update: Add custom domain support with automatic fallback validation - #73

Merged
Boy132 merged 2 commits into
pelican:mainfrom
FlexKleks:main
Jan 3, 2026
Merged

update: Add custom domain support with automatic fallback validation#73
Boy132 merged 2 commits into
pelican:mainfrom
FlexKleks:main

Conversation

@FlexKleks

@FlexKleksFlexKleks commented Jan 3, 2026

Copy link
Copy Markdown
Contributor

Hey, here's a change to my “PasteFox Share” plugin.

Changes

  • Add custom domain support for paste URLs
  • Add automatic API key validation (falls back to anonymous upload if key is invalid/expired)
  • Add automatic custom domain validation (falls back to pastefox.com if domain is inactive/removed)
  • Add translations for all settings page strings
  • Bump version to 1.1.0

Custom Domains

Users can now select a verified custom domain from their PasteFox account to use for paste URLs. The plugin automatically validates that the domain is still active before using it.

Fallback Behavior

If the configured API key or custom domain becomes unavailable, the plugin gracefully falls back to:

  • Anonymous uploads (7-day expiration, public visibility)
  • Default pastefox.com domain

Summary by CodeRabbit

  • New Features

    • Added Custom Domain support to share pastes from your own verified domain.
    • Domain selection now available in plugin settings (requires API key); verified domains shown, inactive ones disabled.
    • Automatic fallback to pastefox.com if a custom domain is unavailable.
  • Chores

    • Updated plugin version to 1.1.0.
    • Added translations and UI text for custom domain management.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitaiBot commented Jan 3, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds Custom Domain support to PasteFox Share: new config key, translations, README updates, plugin version bump, settings UI to fetch/choose verified domains via API, persistence of selection, and upload logic that validates API key and uses the custom domain or falls back to pastefox.com.

Changes

Cohort / File(s)Summary
Documentation & Manifest
pastefox-share/README.md, pastefox-share/plugin.json
README updated with Custom Domain docs; plugin version bumped from 1.0.01.1.0.
Configuration
pastefox-share/config/pastefox-share.php
New config entry: 'custom_domain' => env('PASTEFOX_CUSTOM_DOMAIN').
Translations
pastefox-share/lang/en/messages.php
Adds translation keys for Custom Domain UI and related helper/error texts (section_custom_domain, custom_domain, custom_domain_none, custom_domain_helper, custom_domain_no_api_key, custom_domain_fetch_error, custom_domain_inactive, etc.).
Settings UI & API integration
pastefox-share/src/PasteFoxSharePlugin.php
Adds HTTP client usage and getCustomDomainOptions() to fetch domains from https://pastefox.com/api/domains; settings form extended with a Select for custom_domain; saveSettings() persists choice to PASTEFOX_CUSTOM_DOMAIN.
Upload logic / Validation
pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php
Adds isApiKeyValid() and getActiveCustomDomain(); upload flow now conditionally includes X-API-Key and uses validated custom domain as base URL or falls back to https://pastefox.com; error handling and conditional payload/header logic added.

Sequence Diagrams

sequenceDiagram
participant User
participant Settings as Plugin Settings
participant API as PasteFox API
participant Env as Environment
participant Upload as UploadLogsAction
User->>Settings: Open settings
Settings->>API: GET /api/domains (X-API-Key if present)
API-->>Settings: Domain list (active/inactive)
Settings->>User: Render domain select (inactive → disabled)
User->>Settings: Select domain & Save
Settings->>Env: Persist PASTEFOX_CUSTOM_DOMAIN
Note over User,Upload: Later — user triggers paste upload
User->>Upload: Trigger upload
Upload->>Env: Read api_key & custom_domain
Upload->>API: Validate API key (isApiKeyValid)
Upload->>API: Verify configured domain (getActiveCustomDomain)
alt custom domain valid
Upload->>API: Create paste using custom domain (X-API-Key header)
else fallback
Upload->>API: Create paste at pastefox.com (no X-API-Key)
end
API-->>Upload: Returns paste URL
Upload-->>User: Show paste URL
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Add PasteFox Share plugin #63: Original PasteFox Share plugin introduction; modifies the same files/classes extended here (UploadLogsAction, PasteFoxSharePlugin, config, translations, manifest).

Suggested reviewers

  • lajczi
  • rmartinoscar

Poem

🐰 I sniffed the code, a domain to share,
Hopped through settings with API flair,
Verified names in dropdown air,
Fallback ready, so no despair,
Logs land safely — hop, share, and care!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 16.67% which is insufficient. The required threshold is 80.00%.You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main feature being added: custom domain support with automatic fallback validation, which aligns with all the changes across configuration, UI, translations, and logic.
✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php (2)

149-168: Consider caching API key validation results.

Every log upload triggers an HTTP request to validate the API key. For frequently accessed servers, this creates unnecessary load and latency. API keys rarely change, making them good candidates for caching.

Consider using Laravel's cache to store validation results for a reasonable TTL (e.g., 5-10 minutes):

protectedfunctionisApiKeyValid(?string$apiKey): bool
{
if (blank($apiKey)) {
returnfalse;
}
$cacheKey = 'pastefox_api_key_valid_' . hash('sha256', $apiKey);
returncache()->remember($cacheKey, 300, function () use ($apiKey) {
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
'Content-Type' => 'application/json',
])
->timeout(5)
->get('https://pastefox.com/api/domains')
->json();
return$response['success'] ?? false;
} catch (\Exception$e) {
returnfalse;
}
});
}

Note: If you implement the consolidated API call from the previous comment, apply caching to the consolidated method instead.


118-147: Silent failure in domain validation could hide configuration issues.

While graceful fallback is appropriate for availability issues, completely silent failure makes it difficult for administrators to diagnose why their custom domain isn't working (e.g., typo in domain name, domain not activated, API connectivity issues).

Consider logging a warning when the configured domain is invalid or inactive:

protectedfunctiongetActiveCustomDomain(?string$apiKey): ?string
{
$configuredDomain = config('pastefox-share.custom_domain');
if (blank($configuredDomain) || blank($apiKey)) {
returnnull;
}
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
'Content-Type' => 'application/json',
])
->timeout(5)
->get('https://pastefox.com/api/domains')
->json();
if ($response['success'] ?? false) {
foreach ($response['domains'] ?? [] as$domain) {
if ($domain['domain'] === $configuredDomain && ($domain['isActive'] ?? false)) {
return$configuredDomain;
}
}
+ // Domain configured but not found or inactive
+ logger()->warning("PasteFox custom domain '{$configuredDomain}' is not active, falling back to pastefox.com");
}
} catch (\Exception$e) {
- // Silently fail, fall back to default
+ logger()->warning("Failed to fetch PasteFox domains: {$e->getMessage()}");
}
returnnull;
}

This helps administrators identify configuration issues while maintaining the graceful fallback behavior.

pastefox-share/src/PasteFoxSharePlugin.php (1)

104-140: Add PHPDoc return type annotation to satisfy PHPStan.

The static analysis error indicates the return type lacks a value type specification. Additionally, the Content-Type header is unnecessary for GET requests.

🔎 Proposed fix
+ /**+ * @return array<string, string>+ */
protected function getCustomDomainOptions(): array
{
$options = ['' => trans('pastefox-share::messages.custom_domain_none')];
$apiKey = config('pastefox-share.api_key');
if (blank($apiKey)) {
return $options;
}
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
- 'Content-Type' => 'application/json',
])
->timeout(10)
->get('https://pastefox.com/api/domains')
->json();
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c2ca0f6 and e53dece.

📒 Files selected for processing (6)
  • pastefox-share/README.md
  • pastefox-share/config/pastefox-share.php
  • pastefox-share/lang/en/messages.php
  • pastefox-share/plugin.json
  • pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php
  • pastefox-share/src/PasteFoxSharePlugin.php
🧰 Additional context used
🪛 GitHub Check: PHPStan
pastefox-share/src/PasteFoxSharePlugin.php

[failure] 104-104:
Method FlexKleks\PasteFoxShare\PasteFoxSharePlugin::getCustomDomainOptions() return type has no value type specified in iterable type array.

🪛 markdownlint-cli2 (0.18.1)
pastefox-share/README.md

24-24: Bare URL used

(MD034, no-bare-urls)

🔇 Additional comments (7)
pastefox-share/plugin.json (1)

5-5: LGTM! Appropriate version bump.

The version increment to 1.1.0 correctly reflects the addition of custom domain support as a new feature.

pastefox-share/config/pastefox-share.php (1)

9-9: LGTM! Configuration entry follows established patterns.

The custom domain configuration is consistent with other optional settings in the file.

pastefox-share/lang/en/messages.php (1)

40-49: LGTM! Comprehensive translation coverage.

The translation keys are well-structured and provide clear, user-friendly messaging for the custom domain feature.

pastefox-share/README.md (2)

22-29: LGTM! Clear configuration documentation.

The updated settings table clearly documents all available configuration options including the new custom domain feature.


38-50: LGTM! Comprehensive custom domain documentation.

The documentation clearly explains:

  • How to set up custom domains
  • The verification process
  • Automatic fallback behavior

This provides users with the information needed to configure and use the feature.

pastefox-share/src/PasteFoxSharePlugin.php (2)

87-100: Well-structured conditional UI behavior.

The custom domain section properly gates functionality based on API key presence—disabling the select and showing appropriate helper text when no API key is configured. The disableOptionWhen pattern using the :disabled suffix cleanly prevents selection of inactive domains while still showing them in the dropdown.


150-150: LGTM!

Persistence of the new setting follows the established pattern. Per the AI summary, runtime validation in UploadLogsAction handles fallback when a configured domain becomes inactive.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
pastefox-share/src/PasteFoxSharePlugin.php (2)

138-140: Consider logging errors while maintaining graceful fallback.

Silent error handling prevents debugging issues with the API integration. Consider logging the exception while still returning default options for graceful degradation.

💡 Suggested refactor to add logging
 } catch (\Exception $e) {
- // Silently fail, just return default options+ \Log::warning('Failed to fetch custom domains from PasteFox API', [+ 'error' => $e->getMessage(),+ ]);
}

122-122: Consider extracting the API URL to a constant or config.

Hardcoding the API URL makes it harder to test or support different environments (staging, local development, etc.).

💡 Suggested refactor

Add to your config file:

'api_base_url' => env('PASTEFOX_API_URL', 'https://pastefox.com'),

Then update the code:

- ->get('https://pastefox.com/api/domains')+ ->get(config('pastefox-share.api_base_url') . '/api/domains')
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e53dece and d762559.

📒 Files selected for processing (1)
  • pastefox-share/src/PasteFoxSharePlugin.php
🔇 Additional comments (3)
pastefox-share/src/PasteFoxSharePlugin.php (3)

13-13: LGTM!

The Http facade import is correctly added to support the API call in getCustomDomainOptions().


153-153: LGTM!

The persistence of the custom domain setting follows the established pattern and is correctly implemented.


127-136: The logic is not inconsistent. The status field validates that the domain is registered in the PasteFox system (status === 'ACTIVE'), while isActive represents the user's preference to enable or disable the domain in their dashboard settings. These are complementary validation layers—one system-level, one user-level—not redundant checks.

Additionally, the :disabled suffix pattern is the proper Filament framework convention. Line 94 shows ->disableOptionWhen(fn (string $value): bool => str_ends_with($value, ':disabled')), which is the intended API for presenting disabled options in the select field. This is not a data/UI mixing issue but correct framework integration.

Likely an incorrect or invalid review comment.

Comment threadpastefox-share/src/PasteFoxSharePlugin.php
@Boy132
Boy132 merged commit 39f9c1f into pelican:mainJan 3, 2026
4 checks passed
@Boy132

Copy link
Copy Markdown
Member

For future reference, please create a separate branch for pull requests and don't use main.

@FlexKleks

FlexKleks commented Jan 3, 2026 via email

Copy link
Copy Markdown
ContributorAuthor

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@FlexKleks@Boy132
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

update: Add custom domain support with automatic fallback validation - #73

Merged
Boy132 merged 2 commits into
pelican:mainfrom
FlexKleks:main
Jan 3, 2026
Merged

update: Add custom domain support with automatic fallback validation#73
Boy132 merged 2 commits into
pelican:mainfrom
FlexKleks:main

Conversation

@FlexKleks

@FlexKleksFlexKleks commented Jan 3, 2026

Copy link
Copy Markdown
Contributor

Hey, here's a change to my “PasteFox Share” plugin.

Changes

  • Add custom domain support for paste URLs
  • Add automatic API key validation (falls back to anonymous upload if key is invalid/expired)
  • Add automatic custom domain validation (falls back to pastefox.com if domain is inactive/removed)
  • Add translations for all settings page strings
  • Bump version to 1.1.0

Custom Domains

Users can now select a verified custom domain from their PasteFox account to use for paste URLs. The plugin automatically validates that the domain is still active before using it.

Fallback Behavior

If the configured API key or custom domain becomes unavailable, the plugin gracefully falls back to:

  • Anonymous uploads (7-day expiration, public visibility)
  • Default pastefox.com domain

Summary by CodeRabbit

  • New Features

    • Added Custom Domain support to share pastes from your own verified domain.
    • Domain selection now available in plugin settings (requires API key); verified domains shown, inactive ones disabled.
    • Automatic fallback to pastefox.com if a custom domain is unavailable.
  • Chores

    • Updated plugin version to 1.1.0.
    • Added translations and UI text for custom domain management.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitaiBot commented Jan 3, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds Custom Domain support to PasteFox Share: new config key, translations, README updates, plugin version bump, settings UI to fetch/choose verified domains via API, persistence of selection, and upload logic that validates API key and uses the custom domain or falls back to pastefox.com.

Changes

Cohort / File(s)Summary
Documentation & Manifest
pastefox-share/README.md, pastefox-share/plugin.json
README updated with Custom Domain docs; plugin version bumped from 1.0.01.1.0.
Configuration
pastefox-share/config/pastefox-share.php
New config entry: 'custom_domain' => env('PASTEFOX_CUSTOM_DOMAIN').
Translations
pastefox-share/lang/en/messages.php
Adds translation keys for Custom Domain UI and related helper/error texts (section_custom_domain, custom_domain, custom_domain_none, custom_domain_helper, custom_domain_no_api_key, custom_domain_fetch_error, custom_domain_inactive, etc.).
Settings UI & API integration
pastefox-share/src/PasteFoxSharePlugin.php
Adds HTTP client usage and getCustomDomainOptions() to fetch domains from https://pastefox.com/api/domains; settings form extended with a Select for custom_domain; saveSettings() persists choice to PASTEFOX_CUSTOM_DOMAIN.
Upload logic / Validation
pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php
Adds isApiKeyValid() and getActiveCustomDomain(); upload flow now conditionally includes X-API-Key and uses validated custom domain as base URL or falls back to https://pastefox.com; error handling and conditional payload/header logic added.

Sequence Diagrams

sequenceDiagram
participant User
participant Settings as Plugin Settings
participant API as PasteFox API
participant Env as Environment
participant Upload as UploadLogsAction
User->>Settings: Open settings
Settings->>API: GET /api/domains (X-API-Key if present)
API-->>Settings: Domain list (active/inactive)
Settings->>User: Render domain select (inactive → disabled)
User->>Settings: Select domain & Save
Settings->>Env: Persist PASTEFOX_CUSTOM_DOMAIN
Note over User,Upload: Later — user triggers paste upload
User->>Upload: Trigger upload
Upload->>Env: Read api_key & custom_domain
Upload->>API: Validate API key (isApiKeyValid)
Upload->>API: Verify configured domain (getActiveCustomDomain)
alt custom domain valid
Upload->>API: Create paste using custom domain (X-API-Key header)
else fallback
Upload->>API: Create paste at pastefox.com (no X-API-Key)
end
API-->>Upload: Returns paste URL
Upload-->>User: Show paste URL
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Add PasteFox Share plugin #63: Original PasteFox Share plugin introduction; modifies the same files/classes extended here (UploadLogsAction, PasteFoxSharePlugin, config, translations, manifest).

Suggested reviewers

  • lajczi
  • rmartinoscar

Poem

🐰 I sniffed the code, a domain to share,
Hopped through settings with API flair,
Verified names in dropdown air,
Fallback ready, so no despair,
Logs land safely — hop, share, and care!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 16.67% which is insufficient. The required threshold is 80.00%.You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately describes the main feature being added: custom domain support with automatic fallback validation, which aligns with all the changes across configuration, UI, translations, and logic.
✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php (2)

149-168: Consider caching API key validation results.

Every log upload triggers an HTTP request to validate the API key. For frequently accessed servers, this creates unnecessary load and latency. API keys rarely change, making them good candidates for caching.

Consider using Laravel's cache to store validation results for a reasonable TTL (e.g., 5-10 minutes):

protectedfunctionisApiKeyValid(?string$apiKey): bool
{
if (blank($apiKey)) {
returnfalse;
}
$cacheKey = 'pastefox_api_key_valid_' . hash('sha256', $apiKey);
returncache()->remember($cacheKey, 300, function () use ($apiKey) {
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
'Content-Type' => 'application/json',
])
->timeout(5)
->get('https://pastefox.com/api/domains')
->json();
return$response['success'] ?? false;
} catch (\Exception$e) {
returnfalse;
}
});
}

Note: If you implement the consolidated API call from the previous comment, apply caching to the consolidated method instead.


118-147: Silent failure in domain validation could hide configuration issues.

While graceful fallback is appropriate for availability issues, completely silent failure makes it difficult for administrators to diagnose why their custom domain isn't working (e.g., typo in domain name, domain not activated, API connectivity issues).

Consider logging a warning when the configured domain is invalid or inactive:

protectedfunctiongetActiveCustomDomain(?string$apiKey): ?string
{
$configuredDomain = config('pastefox-share.custom_domain');
if (blank($configuredDomain) || blank($apiKey)) {
returnnull;
}
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
'Content-Type' => 'application/json',
])
->timeout(5)
->get('https://pastefox.com/api/domains')
->json();
if ($response['success'] ?? false) {
foreach ($response['domains'] ?? [] as$domain) {
if ($domain['domain'] === $configuredDomain && ($domain['isActive'] ?? false)) {
return$configuredDomain;
}
}
+ // Domain configured but not found or inactive
+ logger()->warning("PasteFox custom domain '{$configuredDomain}' is not active, falling back to pastefox.com");
}
} catch (\Exception$e) {
- // Silently fail, fall back to default
+ logger()->warning("Failed to fetch PasteFox domains: {$e->getMessage()}");
}
returnnull;
}

This helps administrators identify configuration issues while maintaining the graceful fallback behavior.

pastefox-share/src/PasteFoxSharePlugin.php (1)

104-140: Add PHPDoc return type annotation to satisfy PHPStan.

The static analysis error indicates the return type lacks a value type specification. Additionally, the Content-Type header is unnecessary for GET requests.

🔎 Proposed fix
+ /**+ * @return array<string, string>+ */
protected function getCustomDomainOptions(): array
{
$options = ['' => trans('pastefox-share::messages.custom_domain_none')];
$apiKey = config('pastefox-share.api_key');
if (blank($apiKey)) {
return $options;
}
try {
$response = Http::withHeaders([
'X-API-Key' => $apiKey,
- 'Content-Type' => 'application/json',
])
->timeout(10)
->get('https://pastefox.com/api/domains')
->json();
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c2ca0f6 and e53dece.

📒 Files selected for processing (6)
  • pastefox-share/README.md
  • pastefox-share/config/pastefox-share.php
  • pastefox-share/lang/en/messages.php
  • pastefox-share/plugin.json
  • pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php
  • pastefox-share/src/PasteFoxSharePlugin.php
🧰 Additional context used
🪛 GitHub Check: PHPStan
pastefox-share/src/PasteFoxSharePlugin.php

[failure] 104-104:
Method FlexKleks\PasteFoxShare\PasteFoxSharePlugin::getCustomDomainOptions() return type has no value type specified in iterable type array.

🪛 markdownlint-cli2 (0.18.1)
pastefox-share/README.md

24-24: Bare URL used

(MD034, no-bare-urls)

🔇 Additional comments (7)
pastefox-share/plugin.json (1)

5-5: LGTM! Appropriate version bump.

The version increment to 1.1.0 correctly reflects the addition of custom domain support as a new feature.

pastefox-share/config/pastefox-share.php (1)

9-9: LGTM! Configuration entry follows established patterns.

The custom domain configuration is consistent with other optional settings in the file.

pastefox-share/lang/en/messages.php (1)

40-49: LGTM! Comprehensive translation coverage.

The translation keys are well-structured and provide clear, user-friendly messaging for the custom domain feature.

pastefox-share/README.md (2)

22-29: LGTM! Clear configuration documentation.

The updated settings table clearly documents all available configuration options including the new custom domain feature.


38-50: LGTM! Comprehensive custom domain documentation.

The documentation clearly explains:

  • How to set up custom domains
  • The verification process
  • Automatic fallback behavior

This provides users with the information needed to configure and use the feature.

pastefox-share/src/PasteFoxSharePlugin.php (2)

87-100: Well-structured conditional UI behavior.

The custom domain section properly gates functionality based on API key presence—disabling the select and showing appropriate helper text when no API key is configured. The disableOptionWhen pattern using the :disabled suffix cleanly prevents selection of inactive domains while still showing them in the dropdown.


150-150: LGTM!

Persistence of the new setting follows the established pattern. Per the AI summary, runtime validation in UploadLogsAction handles fallback when a configured domain becomes inactive.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
pastefox-share/src/PasteFoxSharePlugin.php (2)

138-140: Consider logging errors while maintaining graceful fallback.

Silent error handling prevents debugging issues with the API integration. Consider logging the exception while still returning default options for graceful degradation.

💡 Suggested refactor to add logging
 } catch (\Exception $e) {
- // Silently fail, just return default options+ \Log::warning('Failed to fetch custom domains from PasteFox API', [+ 'error' => $e->getMessage(),+ ]);
}

122-122: Consider extracting the API URL to a constant or config.

Hardcoding the API URL makes it harder to test or support different environments (staging, local development, etc.).

💡 Suggested refactor

Add to your config file:

'api_base_url' => env('PASTEFOX_API_URL', 'https://pastefox.com'),

Then update the code:

- ->get('https://pastefox.com/api/domains')+ ->get(config('pastefox-share.api_base_url') . '/api/domains')
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e53dece and d762559.

📒 Files selected for processing (1)
  • pastefox-share/src/PasteFoxSharePlugin.php
🔇 Additional comments (3)
pastefox-share/src/PasteFoxSharePlugin.php (3)

13-13: LGTM!

The Http facade import is correctly added to support the API call in getCustomDomainOptions().


153-153: LGTM!

The persistence of the custom domain setting follows the established pattern and is correctly implemented.


127-136: The logic is not inconsistent. The status field validates that the domain is registered in the PasteFox system (status === 'ACTIVE'), while isActive represents the user's preference to enable or disable the domain in their dashboard settings. These are complementary validation layers—one system-level, one user-level—not redundant checks.

Additionally, the :disabled suffix pattern is the proper Filament framework convention. Line 94 shows ->disableOptionWhen(fn (string $value): bool => str_ends_with($value, ':disabled')), which is the intended API for presenting disabled options in the select field. This is not a data/UI mixing issue but correct framework integration.

Likely an incorrect or invalid review comment.

Comment threadpastefox-share/src/PasteFoxSharePlugin.php
@Boy132
Boy132 merged commit 39f9c1f into pelican:mainJan 3, 2026
4 checks passed
@Boy132

Copy link
Copy Markdown
Member

For future reference, please create a separate branch for pull requests and don't use main.

@FlexKleks

FlexKleks commented Jan 3, 2026 via email

Copy link
Copy Markdown
ContributorAuthor

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@FlexKleks@Boy132