Skip to content

Commit f043082

Browse files
committed
first commit
0 parents  commit f043082

16 files changed

+10831
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.idea
2+
vendor

.phpunit.cache/test-results

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"version":2,"defects":{"SoysalTan\\LaravelPluginSystem\\Tests\\Integration\\LaravelPluginSystemServiceProviderTest::test_service_provider_handles_plugin_controllers_registration":8,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\MakePluginCommandTest::test_creates_plugin_with_volt_view_type":7,"SoysalTan\\LaravelPluginSystem\\Tests\\Feature\\PluginLifecycleTest::test_plugin_controller_binding_lifecycle":8,"SoysalTan\\LaravelPluginSystem\\Tests\\Feature\\PluginLifecycleTest::test_multiple_plugins_coexistence":8,"SoysalTan\\LaravelPluginSystem\\Tests\\Feature\\PluginLifecycleTest::test_plugin_service_dependency_injection_lifecycle":8,"SoysalTan\\LaravelPluginSystem\\Tests\\Feature\\PluginLifecycleTest::test_plugin_with_volt_views_complete_lifecycle":8,"SoysalTan\\LaravelPluginSystem\\Tests\\Feature\\PluginLifecycleTest::test_plugin_with_custom_namespace_lifecycle":8,"SoysalTan\\LaravelPluginSystem\\Tests\\Feature\\PluginLifecycleTest::test_disabled_plugin_lifecycle":8,"SoysalTan\\LaravelPluginSystem\\Tests\\Feature\\PluginLifecycleTest::test_complete_plugin_creation_and_registration_lifecycle":8,"SoysalTan\\LaravelPluginSystem\\Tests\\Feature\\PluginLifecycleTest::test_plugin_view_namespace_registration_lifecycle":8,"SoysalTan\\LaravelPluginSystem\\Tests\\Feature\\PluginLifecycleTest::test_plugin_with_blade_views_complete_lifecycle":8,"SoysalTan\\LaravelPluginSystem\\Tests\\Feature\\PluginLifecycleTest::test_plugin_route_prefixing_lifecycle":8,"SoysalTan\\LaravelPluginSystem\\Tests\\Feature\\PluginLifecycleTest::test_plugin_configuration_customization_lifecycle":8},"times":{"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\PluginManagerTest::test_register_plugin_services_binds_services_as_singletons":0.034,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\PluginManagerTest::test_constructor_sets_plugins_path_from_config":0,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\PluginManagerTest::test_boot_calls_views_routes_and_controllers_registration":0.004,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\PluginManagerTest::test_register_plugin_views_adds_view_locations_and_namespaces":0.005,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\PluginManagerTest::test_register_plugin_configs_loads_plugin_configurations":0.001,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\PluginManagerTest::test_get_plugin_namespace_returns_correct_namespace":0,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\PluginManagerTest::test_register_calls_config_and_services_registration":0.001,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\PluginManagerTest::test_register_plugin_routes_with_plugins_prefix":0.001,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\PluginManagerTest::test_register_plugin_services_binds_interface_to_implementation":0.002,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\PluginManagerTest::test_register_plugin_commands_returns_make_plugin_command":0.001,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\PluginManagerTest::test_register_plugin_controllers_binds_controllers_to_container":0.002,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\PluginManagerTest::test_register_plugin_routes_with_default_prefix":0.001,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\PluginManagerTest::test_register_plugin_configs_handles_missing_plugins_directory":0,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\PluginManagerTest::test_get_plugin_namespace_uses_custom_config":0.001,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\PluginManagerTest::test_handles_non_php_files_in_controllers_directory":0.002,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\PluginManagerTest::test_handles_non_php_files_in_services_directory":0.001,"SoysalTan\\LaravelPluginSystem\\Tests\\Integration\\LaravelPluginSystemServiceProviderTest::test_service_provider_handles_plugin_controllers_registration":0.039,"SoysalTan\\LaravelPluginSystem\\Tests\\Integration\\LaravelPluginSystemServiceProviderTest::test_service_provider_works_with_empty_plugins_directory":0.004,"SoysalTan\\LaravelPluginSystem\\Tests\\Integration\\LaravelPluginSystemServiceProviderTest::test_service_provider_works_with_non_existent_plugins_directory":0,"SoysalTan\\LaravelPluginSystem\\Tests\\Integration\\LaravelPluginSystemServiceProviderTest::test_service_provider_publishes_config_file":0.001,"SoysalTan\\LaravelPluginSystem\\Tests\\Integration\\LaravelPluginSystemServiceProviderTest::test_service_provider_registers_plugin_manager_as_singleton":0.001,"SoysalTan\\LaravelPluginSystem\\Tests\\Integration\\LaravelPluginSystemServiceProviderTest::test_service_provider_handles_plugin_services_registration":0.002,"SoysalTan\\LaravelPluginSystem\\Tests\\Integration\\LaravelPluginSystemServiceProviderTest::test_service_provider_configuration_can_be_overridden":0.001,"SoysalTan\\LaravelPluginSystem\\Tests\\Integration\\LaravelPluginSystemServiceProviderTest::test_plugin_manager_register_is_called_during_service_registration":0.001,"SoysalTan\\LaravelPluginSystem\\Tests\\Integration\\LaravelPluginSystemServiceProviderTest::test_plugin_manager_boot_is_called_during_service_boot":0.005,"SoysalTan\\LaravelPluginSystem\\Tests\\Integration\\LaravelPluginSystemServiceProviderTest::test_service_provider_registers_make_plugin_command":0.042,"SoysalTan\\LaravelPluginSystem\\Tests\\Integration\\LaravelPluginSystemServiceProviderTest::test_service_provider_merges_configuration":0.001,"SoysalTan\\LaravelPluginSystem\\Tests\\Integration\\LaravelPluginSystemServiceProviderTest::test_service_provider_handles_multiple_plugins":0.002,"SoysalTan\\LaravelPluginSystem\\Tests\\Integration\\LaravelPluginSystemServiceProviderTest::test_service_provider_handles_plugin_views_registration":0.005,"SoysalTan\\LaravelPluginSystem\\Tests\\Integration\\LaravelPluginSystemServiceProviderTest::test_service_provider_registers_and_boots_in_correct_order":0.002,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\MakePluginCommandTest::test_creates_plugin_with_default_settings":0.006,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\MakePluginCommandTest::test_creates_plugin_with_volt_view_type":0.091,"SoysalTan\\LaravelPluginSystem\\Tests\\Unit\\MakePluginCommandTest::test_creates_all_required_files":0.082}}

README.md

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
# Laravel Plugin System
2+
3+
A comprehensive Laravel plugin system that provides automatic registration of routes, controllers, services, views, and configurations for modular application development.
4+
5+
## Features
6+
7+
- 🚀 **Automatic Plugin Discovery** - Automatically scans and registers plugins
8+
- 🛣️ **Route Registration** - Auto-registers plugin routes with customizable prefixes
9+
- 🎮 **Controller Binding** - Automatically binds plugin controllers to the service container
10+
- 🔧 **Service Registration** - Registers services as singletons with interface binding support
11+
- 👀 **View Integration** - Seamless integration with Laravel views and Livewire Volt
12+
- ⚙️ **Config Management** - Automatic configuration loading and merging
13+
- 📦 **Plugin Generator** - Artisan command to create new plugins with boilerplate code
14+
15+
## Installation
16+
17+
Install the package via Composer:
18+
19+
```bash
20+
composer require soysaltan/laravel-plugin-system
21+
```
22+
23+
Publish the configuration file:
24+
25+
```bash
26+
php artisan vendor:publish --tag=laravel-plugin-system-config
27+
```
28+
29+
## Configuration
30+
31+
The configuration file `config/laravel-plugin-system.php` allows you to customize:
32+
33+
```php
34+
return [
35+
// Path where plugins are stored
36+
'plugins_path' => app_path('Plugins'),
37+
38+
// Base namespace for plugins
39+
'plugin_namespace' => 'App\\Plugins',
40+
41+
// Whether to prefix routes with 'plugins/'
42+
'use_plugins_prefix_in_routes' => false,
43+
44+
// Default view type for new plugins
45+
'default_view_type' => 'volt', // 'volt' or 'blade'
46+
47+
// Enable/disable Volt support
48+
'enable_volt_support' => true,
49+
];
50+
```
51+
52+
## Usage
53+
54+
### Creating a Plugin
55+
56+
Use the Artisan command to create a new plugin:
57+
58+
```bash
59+
# Create plugin with default view type (configured in config)
60+
php artisan make:plugin MyAwesomePlugin
61+
62+
# Create plugin with Volt views
63+
php artisan make:plugin MyAwesomePlugin --view-type=volt
64+
65+
# Create plugin with traditional Blade views
66+
php artisan make:plugin MyAwesomePlugin --view-type=blade
67+
68+
# Auto-detect best view type based on configuration and availability
69+
php artisan make:plugin MyAwesomePlugin --view-type=auto
70+
```
71+
72+
This creates the following structure:
73+
74+
```
75+
app/Plugins/MyAwesomePlugin/
76+
├── config.php # Plugin configuration
77+
├── routes.php # Plugin routes
78+
├── Controllers/
79+
│ └── MyAwesomePluginController.php # Plugin controller
80+
├── Services/
81+
│ ├── MyAwesomePluginService.php # Plugin service
82+
│ └── MyAwesomePluginServiceInterface.php # Service interface
83+
└── Views/
84+
└── index.blade.php # Livewire Volt component
85+
```
86+
87+
### Plugin Structure
88+
89+
#### Config File (`config.php`)
90+
```php
91+
<?php
92+
return [
93+
'name' => 'MyAwesomePlugin',
94+
'version' => '1.0.0',
95+
'description' => 'MyAwesomePlugin plugin',
96+
'enabled' => true,
97+
];
98+
```
99+
100+
#### Routes File (`routes.php`)
101+
```php
102+
<?php
103+
use Livewire\Volt\Volt;
104+
105+
Volt::route('/', 'index');
106+
```
107+
108+
#### Controller
109+
```php
110+
<?php
111+
namespace App\Plugins\MyAwesomePlugin\Controllers;
112+
113+
use App\Http\Controllers\Controller;
114+
115+
class MyAwesomePluginController extends Controller
116+
{
117+
public function index()
118+
{
119+
// Controller logic
120+
}
121+
}
122+
```
123+
124+
#### Service & Interface
125+
```php
126+
<?php
127+
namespace App\Plugins\MyAwesomePlugin\Services;
128+
129+
interface MyAwesomePluginServiceInterface
130+
{
131+
public function handle(): array;
132+
}
133+
134+
class MyAwesomePluginService implements MyAwesomePluginServiceInterface
135+
{
136+
public function handle(): array
137+
{
138+
return [
139+
'message' => 'MyAwesomePlugin service is working!',
140+
'timestamp' => now()->toISOString(),
141+
];
142+
}
143+
}
144+
```
145+
146+
#### Views
147+
148+
The plugin system supports both **Livewire Volt** and **traditional Blade** views:
149+
150+
**Volt Component (default):**
151+
```php
152+
<?php
153+
new class extends \Livewire\Volt\Component
154+
{
155+
public string $message = 'Welcome to MyAwesomePlugin Plugin!';
156+
157+
public function mount(): void
158+
{
159+
$this->message = 'Hello from MyAwesomePlugin!';
160+
}
161+
}
162+
?>
163+
164+
<div class="p-6 bg-white rounded-lg shadow-md">
165+
<h1 class="text-2xl font-bold text-gray-800 mb-4">MyAwesomePlugin Plugin</h1>
166+
<p class="text-gray-600 mb-4">{{ $message }}</p>
167+
</div>
168+
```
169+
170+
**Traditional Blade View:**
171+
```blade
172+
@extends('layouts.app')
173+
174+
@section('content')
175+
<div class="p-6 bg-white rounded-lg shadow-md">
176+
<h1 class="text-2xl font-bold text-gray-800 mb-4">MyAwesomePlugin Plugin</h1>
177+
<p class="text-gray-600 mb-4">Welcome to MyAwesomePlugin Plugin!</p>
178+
179+
<div class="bg-blue-50 border border-blue-200 rounded-lg p-4">
180+
<h2 class="text-lg font-semibold text-blue-800 mb-2">Plugin Information</h2>
181+
<ul class="text-blue-700 space-y-1">
182+
<li><strong>View Type:</strong> Traditional Blade</li>
183+
</ul>
184+
</div>
185+
</div>
186+
@endsection
187+
```
188+
189+
### Accessing Plugins
190+
191+
Once created, your plugin will be automatically registered and accessible via:
192+
193+
- **Routes**: `http://your-app.com/myawesomeplugin/` (or `/plugins/myawesomeplugin/` if prefix is enabled)
194+
- **Config**: `config('MyAwesomePlugin.name')`
195+
- **Services**: Injected via dependency injection or `app(MyAwesomePluginServiceInterface::class)`
196+
197+
### Service Injection
198+
199+
Plugin services are automatically registered and can be injected:
200+
201+
```php
202+
class SomeController extends Controller
203+
{
204+
public function __construct(
205+
private MyAwesomePluginServiceInterface $pluginService
206+
) {}
207+
208+
public function index()
209+
{
210+
$result = $this->pluginService->handle();
211+
return response()->json($result);
212+
}
213+
}
214+
```
215+
216+
## Advanced Configuration
217+
218+
### Custom Plugin Path
219+
220+
You can change the default plugin path in the configuration:
221+
222+
```php
223+
'plugins_path' => base_path('custom/plugins'),
224+
```
225+
226+
### Custom Namespace
227+
228+
Change the base namespace for plugins:
229+
230+
```php
231+
'plugin_namespace' => 'Custom\\Plugins',
232+
```
233+
234+
### Route Prefixing
235+
236+
Enable route prefixing to add 'plugins/' to all plugin routes:
237+
238+
```php
239+
'use_plugins_prefix_in_routes' => true,
240+
```
241+
242+
## Requirements
243+
244+
- PHP 8.1+
245+
- Laravel 10.0+ or 11.0+
246+
- Livewire Volt 1.0+ (for view components)
247+
248+
## License
249+
250+
This package is open-sourced software licensed under the [MIT license](LICENSE).
251+
252+
## Contributing
253+
254+
Contributions are welcome! Please feel free to submit a Pull Request.
255+
256+
## Support
257+
258+
If you discover any security vulnerabilities or bugs, please send an e-mail to the maintainer.

0 commit comments

Comments
 (0)