- Add ShortUrlGlobalOverview StatsOverviewWidget with split cache strategy: link counts cached forever (invalidated on create/delete), click stats with short TTL (geo_ip.stats_cache_ttl config) - Fix visited_at column in ShortUrlVisit queries (was created_at) - Disable Livewire polling (pollingInterval = null) - Add cache invalidation for global overview in ShortUrl::booted() - Rewrite README asset section: user-facing install instructions clarified, post-autoload-dump tip added, developer recompile notes separated
302 lines
15 KiB
PHP
302 lines
15 KiB
PHP
<?php
|
|
|
|
return [
|
|
'navigation_label' => 'Short Links',
|
|
'navigation_group' => 'Tools',
|
|
'resource_title' => 'Short URL',
|
|
|
|
// Form Tabs
|
|
'tab_link' => 'Link Details',
|
|
'tab_tracking' => 'Tracking Settings',
|
|
'tab_qr_design' => 'QR Code Design',
|
|
|
|
// Link Form Fields
|
|
'destination_url' => 'Destination URL',
|
|
'destination_url_helper' => 'The original URL you want to redirect visitors to.',
|
|
'url_key' => 'Short Key',
|
|
'url_key_helper' => 'Custom key for the short URL (leave empty for auto-generated).',
|
|
'redirect_code' => 'Redirect Code',
|
|
'redirect_code_301' => '301 (Permanent Redirect - better SEO)',
|
|
'redirect_code_302' => '302 (Temporary Redirect - better tracking)',
|
|
'status' => 'Active Status',
|
|
'single_use' => 'Single Use',
|
|
'single_use_helper' => 'Automatically disable this link after it has been visited once.',
|
|
'forward_query_params' => 'Forward Query Parameters',
|
|
'forward_query_params_helper' => 'Append incoming query parameters (like UTM tags) to the destination URL.',
|
|
'expires_at' => 'Expires At',
|
|
'notes' => 'Internal Notes',
|
|
'ga_tracking_id' => 'Google Analytics 4 Measurement ID',
|
|
'ga_tracking_id_helper' => 'Optional G-XXXXXXXXXX ID to track redirects server-side.',
|
|
|
|
// UTM Builder
|
|
'utm_builder' => 'UTM Campaign Builder',
|
|
'utm_builder_helper' => 'Dynamically append UTM parameters to the destination URL. Changes are synchronized in real-time.',
|
|
'utm_source' => 'Campaign Source (utm_source)',
|
|
'utm_source_placeholder' => 'google, newsletter, facebook...',
|
|
'utm_medium' => 'Campaign Medium (utm_medium)',
|
|
'utm_medium_placeholder' => 'cpc, email, social...',
|
|
'utm_campaign' => 'Campaign Name (utm_campaign)',
|
|
'utm_campaign_placeholder' => 'spring_sale, promo_2026...',
|
|
'utm_term' => 'Campaign Term (utm_term)',
|
|
'utm_term_placeholder' => 'yacht_charter, buy_yachts...',
|
|
'utm_content' => 'Campaign Content (utm_content)',
|
|
'utm_content_placeholder' => 'logo_link, text_ad...',
|
|
|
|
// Tracking Form Fields
|
|
'track_visits' => 'Enable Visit Tracking',
|
|
'track_ip' => 'Track IP Address',
|
|
'track_browser' => 'Track Browser Name',
|
|
'track_browser_version' => 'Track Browser Version',
|
|
'track_os' => 'Track Operating System',
|
|
'track_os_version' => 'Track OS Version',
|
|
'track_device_type' => 'Track Device Type (desktop/mobile/tablet)',
|
|
'track_referer' => 'Track Referer URL',
|
|
|
|
// QR Design Fields
|
|
'qr_size' => 'QR Code Size (px)',
|
|
'qr_margin' => 'Quiet Zone Margin',
|
|
'qr_dot_style' => 'Dot Style',
|
|
'qr_fg_color' => 'Foreground Color',
|
|
'qr_bg_color' => 'Background Color',
|
|
'qr_gradient_enabled' => 'Enable Gradient',
|
|
'qr_gradient_from' => 'Gradient Color From',
|
|
'qr_gradient_to' => 'Gradient Color To',
|
|
'qr_gradient_type' => 'Gradient Type',
|
|
'qr_gradient_linear' => 'Linear',
|
|
'qr_gradient_radial' => 'Radial',
|
|
'qr_download' => 'Download QR Code',
|
|
'qr_copied' => 'Short URL copied to clipboard!',
|
|
|
|
// QR Designer Panel UI Labels
|
|
'qr_label_size' => 'Size (px)',
|
|
'qr_label_margin' => 'Margin',
|
|
'qr_label_style' => 'Style',
|
|
'qr_label_color' => 'Color',
|
|
'qr_label_from' => 'From',
|
|
'qr_label_to' => 'To',
|
|
'qr_label_foreground_color' => 'Foreground Color',
|
|
'qr_label_single_color' => 'Single Color',
|
|
'qr_label_gradient' => 'Gradient',
|
|
'qr_label_gradient_type' => 'Gradient Type',
|
|
'qr_label_background' => 'Background',
|
|
'qr_label_transparent' => 'Transparent',
|
|
'qr_label_eye_config' => 'Eye Config',
|
|
'qr_label_eye_square_style' => 'Eye Square Style',
|
|
'qr_label_eye_dot_style' => 'Eye Dot Style',
|
|
'qr_label_eye_color' => 'Eye Color',
|
|
'qr_label_preview' => 'Preview',
|
|
'qr_option_square' => 'Square',
|
|
'qr_option_dots' => 'Dots',
|
|
'qr_option_rounded' => 'Rounded',
|
|
'qr_option_classy' => 'Classy',
|
|
'qr_option_classy_rounded' => 'Classy Rounded',
|
|
'qr_option_extra_rounded' => 'Extra Rounded',
|
|
'qr_option_dot' => 'Dot',
|
|
'qr_chart_visits_label' => 'Visits',
|
|
|
|
// Table Columns
|
|
'col_short_url' => 'Short URL',
|
|
'col_destination_url' => 'Destination URL',
|
|
'col_total_visits' => 'Total Visits',
|
|
'col_status' => 'Status',
|
|
'col_expires_at' => 'Expires At',
|
|
'col_created_at' => 'Created At',
|
|
|
|
// Actions
|
|
'action_stats' => 'Statistics',
|
|
'action_copy' => 'Copy URL',
|
|
'action_qr' => 'QR Code',
|
|
'action_edit' => 'Edit URL',
|
|
'action_delete' => 'Delete URL',
|
|
'action_share' => 'Share Link',
|
|
'share_title' => 'Share Link',
|
|
'share_description' => 'Share this short link via:',
|
|
'share_copy' => 'Copy',
|
|
'share_copied' => 'Short link copied to clipboard!',
|
|
|
|
// Stats Page
|
|
'stats_title' => 'Statistics',
|
|
'stats_tab_statistics' => 'Statistics',
|
|
'stats_tab_visit_logs' => 'Visit Logs',
|
|
'stats_card_total' => 'Total Visits',
|
|
'stats_card_unique' => 'Unique Visitors',
|
|
'stats_card_today' => 'Today',
|
|
'stats_card_week' => 'This Week',
|
|
'stats_card_month' => 'This Month',
|
|
'stats_chart_title' => 'Visits — Last 30 Days',
|
|
'stats_no_chart_data' => 'No visits yet in the last 30 days.',
|
|
'stats_breakdown_countries' => 'Top Countries',
|
|
'stats_breakdown_devices' => 'Device Types',
|
|
'stats_breakdown_browsers' => 'Browsers',
|
|
'stats_breakdown_os' => 'Operating Systems',
|
|
'stats_breakdown_referers' => 'Top Referers',
|
|
'stats_no_country_data' => 'No country data.',
|
|
'stats_no_device_data' => 'No device data.',
|
|
'stats_no_browser_data' => 'No browser data.',
|
|
'stats_no_os_data' => 'No OS data.',
|
|
'stats_no_referer_data' => 'No referer data.',
|
|
'stats_table_title' => 'Visit Logs',
|
|
'stats_btn_back' => 'Back to list',
|
|
'stats_btn_copy' => 'Copy Short URL',
|
|
'stats_col_time' => 'Time',
|
|
'stats_col_country' => 'Country',
|
|
'stats_col_device' => 'Device',
|
|
'stats_col_browser' => 'Browser',
|
|
'stats_col_os' => 'OS',
|
|
'stats_col_ip' => 'IP',
|
|
'stats_no_visits' => 'No visits recorded yet.',
|
|
// Settings Page
|
|
'settings_nav_label' => 'Settings',
|
|
'settings_save_btn' => 'Save Settings',
|
|
'settings_saved' => 'Settings saved successfully!',
|
|
|
|
'settings_tab_general' => 'General',
|
|
'settings_tab_geoip' => 'Geo-IP',
|
|
'settings_tab_ga4' => 'Google Analytics 4',
|
|
|
|
'settings_section_routing' => 'Routing & Redirects',
|
|
'settings_section_queue' => 'Queue',
|
|
'settings_section_geoip' => 'Geo-IP Detection',
|
|
'settings_section_ga4' => 'GA4 Measurement Protocol',
|
|
'settings_ga4_description' => 'Configure server-side Google Analytics 4 event tracking via the Measurement Protocol. Events are sent in the background without blocking the redirect.',
|
|
|
|
'settings_route_prefix' => 'Route Prefix',
|
|
'settings_route_prefix_helper' => 'URL segment before the short key, e.g. "/s/abc123". Change requires a config:clear.',
|
|
'settings_key_length' => 'Auto-generated Key Length',
|
|
'settings_key_length_helper' => 'Number of characters for auto-generated short keys (base62). 6 chars = ~56 billion unique keys.',
|
|
'settings_cache_ttl' => 'Redirect Cache TTL',
|
|
'settings_cache_ttl_helper' => 'Seconds to cache resolved short URL records. Set to 0 to disable (not recommended in production).',
|
|
'settings_queue_connection' => 'Queue Connection',
|
|
'settings_queue_connection_helper' => 'Laravel queue connection used for async visit tracking. Use "sync" for synchronous (slower redirects), or "redis"/"sqs" for production.',
|
|
|
|
'settings_geoip_enabled' => 'Enable Geo-IP Detection',
|
|
'settings_geoip_enabled_helper' => 'Detect and record the visitor\'s country on each visit.',
|
|
'settings_geoip_driver' => 'Detection Driver',
|
|
'settings_geoip_driver_helper' => 'Method used to resolve the visitor country from their IP address.',
|
|
'settings_geoip_driver_headers' => 'CDN Headers (fastest — Cloudflare, CloudFront)',
|
|
'settings_geoip_driver_maxmind' => 'MaxMind Local DB (offline, zero latency)',
|
|
'settings_geoip_driver_ipapi' => 'ip-api.com (free API, 45 req/min limit)',
|
|
'settings_geoip_cache_ttl' => 'Geo-IP Result Cache TTL',
|
|
'settings_geoip_cache_ttl_helper' => 'Seconds to cache the resolved country per hashed IP. 86400 = 24 hours.',
|
|
'settings_geoip_timeout' => 'API Timeout',
|
|
'settings_geoip_timeout_helper' => 'Maximum seconds to wait for an external Geo-IP API response before giving up.',
|
|
'settings_maxmind_path' => 'MaxMind Database Path',
|
|
'settings_maxmind_path_helper' => 'Absolute path to your GeoLite2-Country.mmdb or GeoIP2-Country.mmdb file. Required when driver is set to MaxMind.',
|
|
'settings_maxmind_verify' => 'Verify file',
|
|
'settings_maxmind_verify_ok' => '✅ File found & readable',
|
|
'settings_maxmind_verify_fail' => '❌ File not found or not readable',
|
|
'settings_maxmind_verify_empty' => 'Please enter a path first.',
|
|
|
|
'settings_ga4_api_secret' => 'Measurement Protocol API Secret',
|
|
'settings_ga4_api_secret_helper' => 'Generate this in GA4 → Admin → Data Streams → your stream → Measurement Protocol API secrets.',
|
|
'settings_ga4_firebase_app_id' => 'Firebase App ID (optional)',
|
|
'settings_ga4_firebase_app_id_helper' => 'Required only if tracking a Firebase / app stream. Leave empty for standard web GA4 streams.',
|
|
'settings_ga4_verify' => 'Test connection',
|
|
'settings_ga4_verify_ok' => '✅ API Secret is valid — GA4 connection successful',
|
|
'settings_ga4_verify_fail' => '❌ Invalid API Secret — GA4 rejected the request',
|
|
'settings_ga4_verify_empty' => 'Please enter an API Secret first.',
|
|
'settings_ga4_verify_error' => '⚠️ Connection error — could not reach GA4',
|
|
|
|
'settings_section_buffering' => 'Visit Counters Buffering',
|
|
'settings_buffering_enabled' => 'Buffer Visit Counts in Cache',
|
|
'settings_buffering_helper' => 'When enabled, visit count increments are temporarily buffered in the application cache and must be flushed periodically to the database via "php artisan short-url:sync-counters". This prevents row-locking issues and performance degradation under high-traffic spikes.',
|
|
|
|
// CDN Trust Settings
|
|
'settings_trust_cdn_headers' => 'Trust CDN & Proxy Headers',
|
|
'settings_trust_cdn_headers_helper' => 'Enable this if your app sits behind a CDN (like Cloudflare, AWS CloudFront) or a reverse proxy. This allows extracting the real client IP and country code from CDN headers. Warning: only enable this if you are actually behind a proxy, otherwise client IP addresses can be spoofed!',
|
|
|
|
// Stats View & Export Localization
|
|
'stats_filter_visited_from' => 'Visited From',
|
|
'stats_filter_visited_until' => 'Visited Until',
|
|
'stats_action_export' => 'Export CSV',
|
|
'stats_csv_time' => 'Time',
|
|
'stats_csv_ip' => 'IP Address',
|
|
'stats_csv_country' => 'Country',
|
|
'stats_csv_device' => 'Device',
|
|
'stats_csv_browser' => 'Browser',
|
|
'stats_csv_os' => 'OS',
|
|
'stats_csv_referer' => 'Referer',
|
|
|
|
// Bulk Actions Localization
|
|
'action_enable_selected' => 'Enable selected',
|
|
'action_disable_selected' => 'Disable selected',
|
|
|
|
// Form Sections Localization
|
|
'form_section_options' => 'Options',
|
|
'form_section_notes' => 'Internal Notes',
|
|
'form_section_tracking' => 'Visit Tracking',
|
|
'form_section_tracked_fields' => 'Tracked Fields',
|
|
'form_section_analytics' => 'Third-Party Analytics',
|
|
|
|
// New Dashboard Analytics Keys
|
|
'stats_card_top_source' => 'Top UTM Source',
|
|
'stats_card_top_country' => 'Top Country',
|
|
'stats_filter_date_range' => 'Date Range',
|
|
'stats_preset_24_hours' => 'Last 24 Hours',
|
|
'stats_preset_7_days' => 'Last 7 Days',
|
|
'stats_preset_30_days' => 'Last 30 Days',
|
|
'stats_preset_90_days' => 'Last 90 Days',
|
|
'stats_preset_custom' => 'Custom Range',
|
|
'stats_breakdown_cities' => 'Top Cities',
|
|
'stats_no_city_data' => 'No city data.',
|
|
'stats_breakdown_utm_source' => 'Campaign Sources',
|
|
'stats_breakdown_utm_medium' => 'Campaign Mediums',
|
|
'stats_breakdown_utm_campaign' => 'Campaign Names',
|
|
'stats_no_utm_data' => 'No UTM data recorded.',
|
|
|
|
// New Targeting & Security Tab and fields
|
|
'tab_targeting' => 'Targeting & Security',
|
|
'security_section_title' => 'Security Controls',
|
|
'password' => 'Access Password',
|
|
'password_helper' => 'Require visitors to enter a password before being redirected.',
|
|
'show_warning_page' => 'Show Redirect Warning Page',
|
|
'show_warning_page_helper' => 'Show an intermediate screen warning visitors about external redirection (NSFW/phishing protection).',
|
|
'targeting_type' => 'Targeting Strategy',
|
|
'targeting_type_none' => 'None (Direct Redirect)',
|
|
'targeting_type_device' => 'Device-Based Redirects',
|
|
'targeting_type_country' => 'Country-Based (Geo-IP) Redirects',
|
|
'targeting_type_rotation' => 'A/B Split Rotation',
|
|
'device_targeting_rules' => 'Device Rules',
|
|
'country_targeting_rules' => 'Country Rules',
|
|
'rotation_targeting_rules' => 'Rotation Targets',
|
|
'device_mobile' => 'Mobile Destination URL',
|
|
'device_tablet' => 'Tablet Destination URL',
|
|
'device_desktop' => 'Desktop Destination URL',
|
|
'country_code' => 'Country Code',
|
|
'rotation_url' => 'Destination URL',
|
|
'rotation_weight' => 'Traffic Weight',
|
|
'rotation_weight_helper' => 'Percentage of traffic to route to this URL (e.g. 50 for 50%). Weights are balanced proportionally.',
|
|
|
|
// New Settings Page Fields
|
|
'settings_tab_advanced' => 'Performance & Security',
|
|
'settings_section_aggregation' => 'High-Traffic Log Management',
|
|
'settings_retention_days' => 'Raw Log Retention Period',
|
|
'settings_retention_days_helper' => 'Select the duration for which you want to keep detailed raw click logs before they are deleted.',
|
|
'settings_aggregation_enabled' => 'Enable Automatic Daily Pruning & Aggregation',
|
|
'settings_aggregation_enabled_helper' => 'When enabled, the plugin automatically registers a daily task in the scheduler (at 02:00) to aggregate visits into daily statistics and delete raw logs older than the chosen retention period.',
|
|
'retention_30_days' => '30 Days',
|
|
'retention_60_days' => '60 Days',
|
|
'retention_90_days' => '90 Days',
|
|
'retention_180_days' => '180 Days (Half Year)',
|
|
'retention_365_days' => '365 Days (1 Year)',
|
|
'retention_730_days' => '2 Years',
|
|
'settings_section_rate_limiting' => 'Rate Limiting / Bot Protection',
|
|
'settings_rate_limiting_enabled' => 'Enable Limit Protection',
|
|
'settings_rate_limiting_enabled_helper' => 'Limit the rate of redirects per client IP address.',
|
|
'settings_rate_limiting_max_attempts' => 'Max Redirects Allowed',
|
|
'settings_rate_limiting_max_attempts_helper' => 'Maximum allowed redirection requests within the decay window.',
|
|
'settings_rate_limiting_decay_seconds' => 'Decay Window (Seconds)',
|
|
'settings_rate_limiting_decay_seconds_helper' => 'Time period for the rate limiter.',
|
|
|
|
// Views
|
|
'password_title' => 'Password Required',
|
|
'password_description' => 'This link is password-protected. Please enter the correct password to continue.',
|
|
'password_placeholder' => 'Enter password',
|
|
'password_btn_unlock' => 'Unlock & Redirect',
|
|
'password_error' => 'Incorrect password.',
|
|
'warning_title' => 'Security Redirect Warning',
|
|
'warning_description' => 'You are leaving this secure portal and being redirected to an external target link. Please ensure you trust the address below:',
|
|
'warning_btn_continue' => 'Continue to Destination',
|
|
'warning_btn_back' => 'Go Back',
|
|
];
|