quvel/core
Composer 安装命令:
composer require quvel/core
包简介
Core foundation package for Quvel framework - Device management, push notifications, platform detection, distributed tracing, and more for Laravel applications
关键字:
README 文档
README
A Laravel package providing essential utilities for full-stack applications including device management, push notifications, platform detection, locale handling, distributed tracing, and more.
Installation
Step 1: Add the Package
Install via composer:
composer require quvel/core
Step 2: Publish Configuration
Publish the configuration file to config/quvel.php:
php artisan vendor:publish --tag=quvel-config
This creates config/quvel.php with all available options.
Step 3: Publish and Run Migrations
Publish the migrations:
php artisan vendor:publish --tag=quvel-migrations
This publishes:
2024_01_01_000000_create_platform_settings_table- For platform-specific settings2024_01_01_000001_create_user_devices_table- For device management
Note: Migration filenames include timestamps (YYYY_MM_DD_HHMMSS format) to ensure they run in the correct order. The timestamps are part of Laravel's convention for managing database schema versions.
Run the migrations:
php artisan migrate
Step 4: Configure Environment Variables
Add the following to your .env file (optional, depending on features you use):
# Captcha (Google reCAPTCHA) CAPTCHA_ENABLED=true RECAPTCHA_SECRET_KEY=your-secret-key RECAPTCHA_SITE_KEY=your-site-key RECAPTCHA_SCORE_THRESHOLD=0.5 # Push Notifications PUSH_ENABLED=true PUSH_DRIVERS=fcm,apns,web # FCM (Firebase Cloud Messaging) FCM_SERVER_KEY=your-fcm-server-key FCM_PROJECT_ID=your-fcm-project-id # APNS (Apple Push Notification Service) APNS_KEY_PATH=/path/to/apns/key.p8 APNS_KEY_ID=your-key-id APNS_TEAM_ID=your-team-id APNS_BUNDLE_ID=com.yourapp.bundle APNS_ENVIRONMENT=sandbox # or 'production' # Web Push (VAPID) VAPID_SUBJECT=mailto:your@email.com VAPID_PUBLIC_KEY=your-public-key VAPID_PRIVATE_KEY=your-private-key # Device Management DEVICES_ENABLED=true DEVICES_ALLOW_ANONYMOUS=false DEVICES_CLEANUP_DAYS=90 DEVICES_MAX_PER_USER=10 # Frontend/Redirects FRONTEND_URL=http://localhost:3000 FRONTEND_REDIRECT_MODE=universal_links # or 'custom_scheme', 'landing_page', 'web_only' FRONTEND_CUSTOM_SCHEME=myapp FRONTEND_LANDING_PAGE_TIMEOUT=5 # Security SECURITY_TRUSTED_IPS=127.0.0.1,::1 SECURITY_API_KEY=your-internal-api-key SECURITY_DISABLE_IP_CHECK=false SECURITY_DISABLE_KEY_CHECK=false # Tracing TRACING_ENABLED=true TRACING_ACCEPT_EXTERNAL=true # Locale LOCALE_ALLOWED=en,es,fr LOCALE_FALLBACK=en LOCALE_NORMALIZE=true # Platform Detection HEADER_PLATFORM=X-Platform HEADER_TRACE_ID=X-Trace-ID # Public IDs PUBLIC_ID_DRIVER=ulid # or 'uuid' PUBLIC_ID_COLUMN=public_id
Step 5: Verify Installation
Check that the package is discovered:
php artisan package:discover
You should see quvel/core in the list.
Check available commands:
php artisan list
Optional: Publish Additional Assets
# Publish API routes for device management (optional - only if you want to customize them) php artisan vendor:publish --tag=quvel-routes # Publish language files php artisan vendor:publish --tag=quvel-lang # Publish views (landing pages, etc.) php artisan vendor:publish --tag=quvel-views
Important: Routes are disabled by default. To enable device management routes, add to your .env:
# Enable device management API routes QUVEL_DEVICE_ROUTES_ENABLED=true # Enable platform settings API routes QUVEL_PLATFORM_SETTINGS_ROUTES_ENABLED=true
You do not need to publish the routes file unless you want to customize the route definitions. The routes will work from the package once enabled via environment variables.
Troubleshooting
Package not discovered:
- Clear bootstrap cache:
rm bootstrap/cache/*.php - Run:
php artisan package:discover - Check
composer.jsonfor correct repository path
Migrations already exist:
- Migrations are automatically loaded from the package
- Only publish if you need to customize them
Config changes not taking effect:
- Run:
php artisan config:clear - Check that
.envvalues are correct
Table of Contents
- Captcha
- Device Management
- Push Notifications
- Platform Detection
- Locale Management
- Distributed Tracing
- Public IDs
- Redirects
- Security
- Middleware
- Publishing Assets
Captcha
Protect your endpoints from bots and automated attacks using Google reCAPTCHA.
Configuration
// config/quvel.php 'captcha' => [ 'enabled' => env('CAPTCHA_ENABLED', true), 'driver' => env('CAPTCHA_DRIVER', \Quvel\Core\Captcha\GoogleRecaptchaDriver::class), 'score_threshold' => env('RECAPTCHA_SCORE_THRESHOLD', 0.5), 'timeout' => env('CAPTCHA_TIMEOUT', 30), ],
CAPTCHA_ENABLED=true RECAPTCHA_SECRET_KEY=your-secret-key RECAPTCHA_SITE_KEY=your-site-key
Usage
Verify captcha:
use Quvel\Core\Facades\Captcha; $result = Captcha::verify($token, $request->ip()); if ($result->isSuccessful()) { // Continue with request } // Check reCAPTCHA v3 score if ($result->hasScore() && $result->score >= 0.5) { // High confidence user }
Protect routes with middleware:
Route::post('/register', function () { // Protected by captcha })->middleware('captcha'); // Custom input field Route::post('/login', function () { // ... })->middleware('captcha:recaptcha_response');
Custom Captcha Driver
use Quvel\Core\Contracts\CaptchaDriverInterface; use Quvel\Core\Captcha\CaptchaVerificationResult; class HCaptchaDriver implements CaptchaDriverInterface { public function verify(string $token, ?string $ip = null, ?string $action = null): CaptchaVerificationResult { // Your verification logic return CaptchaVerificationResult::success(); } public function supportsScoring(): bool { return false; } public function getDefaultScoreThreshold(): ?float { return null; } }
Set in config:
'captcha' => [ 'driver' => \App\Captcha\HCaptchaDriver::class, ],
Events
use Quvel\Core\Events\CaptchaVerifySuccess; use Quvel\Core\Events\CaptchaVerifyFailed; Event::listen(CaptchaVerifyFailed::class, function ($event) { Log::warning('Captcha failed', [ 'ip' => $event->ipAddress, 'reason' => $event->reason, ]); });
Device Management
Track user devices across web, mobile, and desktop platforms. Register devices, manage push tokens, and maintain device lifecycle.
Configuration
// config/quvel.php 'devices' => [ 'enabled' => env('DEVICES_ENABLED', true), 'allow_anonymous' => env('DEVICES_ALLOW_ANONYMOUS', false), 'cleanup_inactive_after_days' => env('DEVICES_CLEANUP_DAYS', 90), 'max_devices_per_user' => env('DEVICES_MAX_PER_USER', 10), ],
Usage
Register a device:
use Quvel\Core\Facades\Device; $device = Device::registerDevice([ 'device_id' => 'device-123', 'platform' => 'ios', 'device_name' => 'John's iPhone', 'push_token' => 'fcm-token', 'push_provider' => 'fcm', ]);
Manage devices:
// Update push token DeviceManager::updatePushToken('device-123', 'new-token', 'fcm'); // Deactivate device DeviceManager::deactivateDevice('device-123', 'User logged out'); // Get user's devices $devices = DeviceManager::getUserDevices(auth()->id());
Device Model
use Quvel\Core\Models\UserDevice; // Get active devices for a user $devices = UserDevice::forUser($userId)->active()->get(); // Find by device ID $device = UserDevice::where('device_id', 'device-123')->first(); // Check if device has valid push token if ($device->hasValidPushToken()) { // Send notification } // Platform filtering $iosDevices = UserDevice::forPlatform('ios')->get();
API Routes
Publish and enable device routes:
php artisan vendor:publish --tag=quvel-routes
// config/quvel.php 'routes' => [ 'devices' => [ 'enabled' => env('QUVEL_DEVICE_ROUTES_ENABLED', false), 'prefix' => 'api/devices', 'name' => 'devices.', 'middleware' => ['api', 'auth:sanctum'], ], ],
Available endpoints:
POST /api/devices/register- Register a devicePOST /api/devices/push-token- Update push tokenPOST /api/devices/deactivate- Deactivate deviceGET /api/devices/list- List user's devices
Middleware
Automatically detect and track devices:
$device = $request->attributes->get('device'); $deviceId = $request->attributes->get('device_id');
Events
use Quvel\Core\Events\DeviceRegistered; use Quvel\Core\Events\DeviceRemoved; Event::listen(DeviceRegistered::class, function ($event) { Log::info('Device registered', [ 'device_id' => $event->deviceId, 'platform' => $event->platform, ]); });
Push Notifications
Send push notifications to user devices across multiple platforms (FCM, APNS, Web Push). Supports device targeting and batch processing.
Configuration
// config/quvel.php 'push' => [ 'enabled' => env('PUSH_ENABLED', true), 'drivers' => explode(',', env('PUSH_DRIVERS', 'fcm,apns,web')), 'fcm' => [ 'server_key' => env('FCM_SERVER_KEY'), 'project_id' => env('FCM_PROJECT_ID'), ], 'apns' => [ 'key_path' => env('APNS_KEY_PATH'), 'key_id' => env('APNS_KEY_ID'), 'team_id' => env('APNS_TEAM_ID'), 'bundle_id' => env('APNS_BUNDLE_ID'), 'environment' => env('APNS_ENVIRONMENT', 'sandbox'), ], 'web_push' => [ 'vapid_subject' => env('VAPID_SUBJECT'), 'vapid_public_key' => env('VAPID_PUBLIC_KEY'), 'vapid_private_key' => env('VAPID_PRIVATE_KEY'), ], 'batch_size' => env('PUSH_BATCH_SIZE', 1000), ], 'targeting' => [ 'default_scope' => env('TARGETING_DEFAULT_SCOPE', 'requesting_device'), ],
Usage
Send to device:
use Quvel\Core\Facades\PushNotification; $success = PushNotification::sendToDevice( device: $device, title: 'New Message', body: 'You have a new message', data: ['message_id' => 123] );
Send to multiple devices:
$results = PushNotification::sendToDevices( devices: $devices, title: 'Update Available', body: 'A new version is available' ); // Returns: ['device-123' => true, 'device-456' => false, ...]
Device Targeting
Get target devices:
use Quvel\Core\Facades\Targeting; // Get devices for targeting scope $devices = Targeting::getTargetDevices( requestingDevice: $device, userId: auth()->id(), scope: 'all_user_devices' // or 'requesting_device' ); // Then send to those devices PushNotification::sendToDevices($devices, $title, $body);
Targeting scopes:
requesting_device- Only the device making the requestall_user_devices- All of the user's active devices
Custom Push Driver
use Quvel\Core\Contracts\PushDriver; use Quvel\Core\Models\UserDevice; class CustomPushDriver implements PushDriver { public function getName(): string { return 'custom'; } public function supports(string $platform): bool { return $platform === 'my-platform'; } public function isConfigured(): bool { return !empty(config('services.custom_push.api_key')); } public function send(UserDevice $device, string $title, string $body, array $data = []): bool { // Your sending logic return true; } }
Register in service provider:
app(PushManager::class)->extend('custom', function () { return new CustomPushDriver(); });
Events
use Quvel\Core\Events\PushNotificationSent; use Quvel\Core\Events\PushNotificationFailed; Event::listen(PushNotificationSent::class, function ($event) { Log::info('Push sent', [ 'devices' => $event->deviceIds, 'title' => $event->title, ]); });
Platform Detection
Detect the platform (web, mobile, desktop) from which requests originate.
Configuration
// config/quvel.php 'headers' => [ 'platform' => env('HEADER_PLATFORM'), // Defaults to 'X-Platform' ],
Usage
use Quvel\Core\Facades\PlatformDetector; $platform = Platform::getPlatform(); // 'web', 'mobile', or 'desktop' if (Platform::isPlatform('mobile')) { // Mobile-specific logic }
Platform tags:
use Quvel\Core\Platform\PlatformTag; PlatformTag::IOS->value; // 'ios' PlatformTag::ANDROID->value; // 'android' PlatformTag::ELECTRON->value; // 'electron' PlatformTag::TABLET->value; // 'tablet' PlatformTag::SCREEN_LG->value; // 'screen:lg' $tag = PlatformTag::tryFrom('ios'); $mode = $tag->getMainMode(); // 'mobile' $category = $tag->getCategory(); // 'os'
Available platform tags:
- Runtime:
web,capacitor,cordova,electron,tauri - OS:
ios,android,macos,windows,linux - Form Factor:
mobile,tablet,desktop - Screen Sizes:
screen:xs,screen:sm,screen:md,screen:lg,screen:xl
Frontend Integration
// Multi-tag platform detection (comma-separated) // iPhone in Capacitor fetch('/api/endpoint', { headers: { 'X-Platform': 'capacitor,ios,mobile,screen:sm' } }); // iPad in Safari fetch('/api/endpoint', { headers: { 'X-Platform': 'web,ios,tablet,screen:lg' } }); // Electron on macOS fetch('/api/endpoint', { headers: { 'X-Platform': 'electron,macos,desktop,screen:xl' } });
Locale Management
Automatic locale detection and management from request headers.
Configuration
// config/quvel.php 'locale' => [ 'allowed_locales' => explode(',', env('LOCALE_ALLOWED', 'en')), 'fallback_locale' => env('LOCALE_FALLBACK', 'en'), 'normalize_locales' => env('LOCALE_NORMALIZE', true), // en-US -> en ],
Usage
use Quvel\Core\Facades\Locale; // Detect locale from request $locale = $request->header('Accept-Language'); // Middleware automatically detects and sets locale // Access via Laravel's app()->getLocale()
Locale is detected from:
Accept-Languageheader- Falls back to configured default
Distributed Tracing
Track requests across your distributed system with automatic trace ID generation and propagation.
Configuration
// config/quvel.php 'tracing' => [ 'enabled' => env('TRACING_ENABLED', true), 'accept_external_trace_ids' => env('TRACING_ACCEPT_EXTERNAL', true), ], 'headers' => [ 'trace_id' => env('HEADER_TRACE_ID'), // Defaults to 'X-Trace-ID' ],
Usage
use Quvel\Core\Facades\Trace; // Middleware automatically generates trace IDs // Access from Laravel's Context use Illuminate\Support\Facades\Context; $traceId = Context::get('trace_id');
Frontend Integration
const traceId = generateUUID(); fetch('/api/endpoint', { headers: { 'X-Trace-ID': traceId } });
Public IDs
Generate user-facing IDs (ULIDs or UUIDs) for models instead of exposing database IDs.
Configuration
// config/quvel.php 'public_id' => [ 'driver' => env('PUBLIC_ID_DRIVER', 'ulid'), // 'ulid' or 'uuid' 'column' => env('PUBLIC_ID_COLUMN', 'public_id'), ],
Usage
Add trait to your model:
use Quvel\Core\Concerns\HasPublicId; class Order extends Model { use HasPublicId; }
Auto-generates public ID on creation:
$order = Order::create([...]); echo $order->public_id; // '01HQ...' (ULID) or 'uuid-here' // Find by public ID $order = Order::wherePublicId('01HQ...')->first();
Route Model Binding
Route::get('/orders/{order:public_id}', function (Order $order) { return $order; });
Redirects
Smart redirects that work across web, mobile, and desktop platforms using universal links, custom schemes, or landing pages.
Configuration
// config/quvel.php 'frontend' => [ 'url' => env('FRONTEND_URL', 'http://localhost:3000'), 'custom_scheme' => env('FRONTEND_CUSTOM_SCHEME'), 'redirect_mode' => env('FRONTEND_REDIRECT_MODE', 'universal_links'), // Options: 'universal_links', 'custom_scheme', 'landing_page', 'web_only' 'landing_page_timeout' => env('FRONTEND_LANDING_PAGE_TIMEOUT', 5), 'allowed_redirect_domains' => explode(',', env('FRONTEND_ALLOWED_DOMAINS', '')), ],
Usage
use Quvel\Core\Facades\Redirect; // Redirect to frontend path return Redirect::redirect('/dashboard'); // With query params return Redirect::redirect('/orders/123', ['status' => 'new']); // With message return Redirect::redirectWithMessage('/login', 'Please sign in'); // Get URL without redirecting $url = Redirect::getUrl('/profile');
Redirect Modes
Universal Links (recommended): Uses HTTPS URLs that open the app if installed, otherwise open in browser.
FRONTEND_REDIRECT_MODE=universal_links FRONTEND_URL=https://app.example.com
Custom Scheme: Uses custom URL scheme (myapp://).
FRONTEND_REDIRECT_MODE=custom_scheme FRONTEND_CUSTOM_SCHEME=myapp
Landing Page: Shows countdown page before redirect.
FRONTEND_REDIRECT_MODE=landing_page FRONTEND_LANDING_PAGE_TIMEOUT=5
Web Only: Always redirects to web URL.
FRONTEND_REDIRECT_MODE=web_only
Security
Internal Request Validation
Protect internal endpoints from external access:
// config/quvel.php 'security' => [ 'internal_requests' => [ 'trusted_ips' => explode(',', env('SECURITY_TRUSTED_IPS', '127.0.0.1,::1')), 'api_key' => env('SECURITY_API_KEY'), 'disable_ip_check' => env('SECURITY_DISABLE_IP_CHECK', false), 'disable_key_check' => env('SECURITY_DISABLE_KEY_CHECK', false), ], ],
Protect routes:
Route::middleware('internal-only')->group(function () { Route::get('/internal/stats', [StatsController::class, 'index']); });
Frontend SSR integration:
// In your SSR server fetch('http://api.internal/endpoint', { headers: { 'X-SSR-Key': process.env.SECURITY_API_KEY } });
Middleware
Available Middleware
'captcha' // Verify captcha token 'config-gate' // Gate access based on config 'device-detection' // Detect and track devices 'internal-only' // Restrict to internal requests 'locale' // Auto-detect and set locale 'platform-detection' // Detect platform (web/mobile/desktop) 'trace' // Generate/propagate trace IDs
Global Configuration
// config/quvel.php 'middleware' => [ 'aliases' => [ 'captcha' => \Quvel\Core\Http\Middleware\VerifyCaptcha::class, 'config-gate' => \Quvel\Core\Http\Middleware\ConfigGate::class, 'device-detection' => \Quvel\Core\Http\Middleware\DeviceDetection::class, 'internal-only' => \Quvel\Core\Http\Middleware\InternalOnly::class, 'locale' => \Quvel\Core\Http\Middleware\LocaleMiddleware::class, 'platform-detection' => \Quvel\Core\Http\Middleware\PlatformDetection::class, 'trace' => \Quvel\Core\Http\Middleware\TraceMiddleware::class, ], 'groups' => [ 'web' => [ 'platform-detection', 'device-detection', 'locale', 'trace', ], 'api' => [ 'platform-detection', 'device-detection', 'locale', 'trace', ], ], ],
Extending the Package
Custom Implementations
All core services use contracts and can be extended or replaced:
use Quvel\Core\Device\Device as BaseManager; class CustomDeviceManager extends BaseManager { public function registerDevice(array $deviceData): UserDevice { $device = parent::registerDevice($deviceData); // Add custom logic (webhooks, etc.) return $device; } } // Bind in service provider $this->app->bind( \Quvel\Core\Contracts\Device::class, \App\Services\CustomDeviceManager::class );
Available Contracts
CaptchaVerifierCaptchaDriverInterfaceDeviceManagerLocaleResolverPlatformDetectorPublicIdGeneratorPushManagerPushDriverAppRedirectorTraceIdGenerator
Events
Device Events
DeviceRegistered- Device registeredDeviceRemoved- Device deactivated
Push Notification Events
PushNotificationSent- Notification sent successfullyPushNotificationFailed- Notification failed
Captcha Events
CaptchaVerifySuccess- Captcha verification succeededCaptchaVerifyFailed- Captcha verification failed
Trace Events
PublicTraceAccepted- External trace ID accepted
Publishing Assets
# Publish everything php artisan vendor:publish --provider="Quvel\Core\Providers\CoreServiceProvider" # Publish specific assets php artisan vendor:publish --tag=quvel-config php artisan vendor:publish --tag=quvel-migrations php artisan vendor:publish --tag=quvel-routes php artisan vendor:publish --tag=quvel-lang php artisan vendor:publish --tag=quvel-views
License
MIT
quvel/core 适用场景与选型建议
quvel/core 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 55 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 11 月 02 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「mobile」 「captcha」 「laravel」 「push-notifications」 「pwa」 「distributed-tracing」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 quvel/core 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 quvel/core 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 quvel/core 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Beyonic PHP Library
Diese Contao 4 Erweiterung stellt Google reCAPTCHA V2 in Form eines neuen Formularfeldes im Formulargenerator bereit. This extension provides Google reCAPTCHA V2 in the form of a new form field in the form generator of Contao Open Source CMS.
Two Captcha
The skeleton application for NativePHP for Mobile.
PHP SDK for Mobile Message SMS API
Laravel 5 Securimage helper
统计信息
- 总下载量: 55
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 27
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-11-02