Skip to content

Commit 533ebc2

Browse files
committed
Optimization
1 parent 517a40e commit 533ebc2

File tree

11 files changed

+359
-336
lines changed

11 files changed

+359
-336
lines changed

README.md

Lines changed: 8 additions & 198 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@
99

1010
A powerful modular extension framework for Laravel 12+ that enables you to build scalable, maintainable applications with runtime discovery, activation control, and scaffolding utilities.
1111

12-
## 🚀 Features
12+
## 🚀 Key Features
1313

1414
- **Runtime Discovery**: Automatically discover and load extensions from configured directories
1515
- **Activation Management**: Enable/disable extensions with dependency checks and protection mechanisms
1616
- **Flexible Storage**: Choose between file-based or database activators for persistence
1717
- **Rich API**: Manage extensions through facade, HTTP API, and Artisan commands
1818
- **Async Operations**: Queue enable/disable/install operations with status monitoring
19-
- **Dependency Resolution**: Smart dependency management with conflict detection
2019
- **Code Generation**: Scaffold new extensions with customizable stubs
2120
- **Event System**: Comprehensive event dispatching for extension lifecycle
2221
- **Multi-type Support**: Support for different extension types (Modules, Themes, etc.)
@@ -37,13 +36,13 @@ composer require gigabait93/laravel-extensions
3736
Publish the configuration file:
3837

3938
```bash
40-
php artisan extensions:publish --tag=extensions-config
39+
php artisan vendor:publish --tag=extensions-config
4140
```
4241

4342
If using database activator, publish and run migrations:
4443

4544
```bash
46-
php artisan extensions:publish --tag=extensions-migrations
45+
php artisan vendor:publish --tag=extensions-migrations
4746
php artisan migrate
4847
```
4948

@@ -53,103 +52,25 @@ Discover existing extensions:
5352
php artisan extensions:discover
5453
```
5554

56-
## 🏗️ Extension Structure
57-
58-
Extensions are organized in type-based directories:
59-
60-
```
61-
extensions/
62-
├── Modules/
63-
│ ├── Blog/
64-
│ │ ├── extension.json
65-
│ │ ├── composer.json
66-
│ │ ├── helpers.php
67-
│ │ ├── Providers/
68-
│ │ │ └── BlogServiceProvider.php
69-
│ │ ├── Routes/
70-
│ │ │ ├── web.php
71-
│ │ │ └── api.php
72-
│ │ ├── Http/
73-
│ │ │ └── Controllers/
74-
│ │ ├── Models/
75-
│ │ ├── Database/
76-
│ │ │ ├── Migrations/
77-
│ │ │ └── Seeders/
78-
│ │ └── Resources/
79-
│ │ └── views/
80-
│ └── Shop/
81-
├── Themes/
82-
│ └── Admin/
83-
└── Plugins/
84-
└── Analytics/
85-
```
86-
87-
### Extension Manifest (extension.json)
88-
89-
```json
90-
{
91-
"id": "blog",
92-
"name": "Blog",
93-
"provider": "Modules\\Blog\\Providers\\BlogServiceProvider",
94-
"type": "Modules",
95-
"description": "Simple blog module",
96-
"author": "John Doe",
97-
"version": "1.0.0",
98-
"compatible_with": "^12.0",
99-
"requires_extensions": ["base"],
100-
"meta": {
101-
"category": "content"
102-
}
103-
}
104-
```
105-
106-
## 🎨 Usage
107-
108-
### Basic Operations
55+
## 🎯 Quick Start
10956

11057
```php
11158
use Gigabait93\Extensions\Facades\Extensions;
11259

11360
// Get all extensions
11461
$extensions = Extensions::all();
11562

116-
// Get active extensions
117-
$active = Extensions::enabled();
118-
119-
// Find specific extension
120-
$blog = Extensions::find('blog');
121-
122-
// Get extension by ID
123-
$extension = Extensions::get('blog');
124-
12563
// Enable extension
12664
Extensions::enable('blog');
12765

128-
// Disable extension
66+
// Disable extension
12967
Extensions::disable('blog');
13068

131-
// Install extension dependencies
132-
Extensions::installDependencies('blog');
133-
13469
// Install dependencies and enable
13570
Extensions::installAndEnable('blog');
13671
```
13772

138-
### Async Operations
139-
140-
```php
141-
use Gigabait93\Extensions\Jobs\ExtensionEnableJob;
142-
use Gigabait93\Extensions\Jobs\ExtensionDisableJob;
143-
use Gigabait93\Extensions\Jobs\ExtensionInstallDepsJob;
144-
145-
// Queue extension operations
146-
Extensions::enableAsync('blog');
147-
Extensions::disableAsync('shop');
148-
Extensions::installDepsAsync('analytics');
149-
Extensions::installAndEnableAsync('blog');
150-
```
151-
152-
### Artisan Commands
73+
### Basic Commands
15374

15475
```bash
15576
# List all extensions
@@ -158,133 +79,22 @@ php artisan extensions:list
15879
# Enable extension
15980
php artisan extensions:enable blog
16081

161-
# Disable extension
162-
php artisan extensions:disable blog
163-
164-
# Install dependencies
165-
php artisan extensions:install-deps blog
166-
16782
# Create new extension
16883
php artisan extensions:make Blog --type=module
169-
170-
# Migrate extensions
171-
php artisan extensions:migrate
172-
173-
# Publish extension assets
174-
php artisan extensions:publish blog
175-
176-
# Reload extensions cache
177-
php artisan extensions:reload
17884
```
17985

180-
## 🎭 Events
181-
182-
The package dispatches various events during extension lifecycle:
183-
184-
```php
185-
use Gigabait93\Extensions\Events\{
186-
ExtensionEnabledEvent,
187-
ExtensionDisabledEvent,
188-
ExtensionDiscoveredEvent,
189-
ExtensionDeletedEvent,
190-
ExtensionDepsInstalledEvent
191-
};
192-
193-
// Listen to extension events
194-
Event::listen(ExtensionEnabledEvent::class, function ($event) {
195-
logger()->info("Extension {$event->extension->name} was enabled");
196-
});
197-
198-
Event::listen(ExtensionDisabledEvent::class, function ($event) {
199-
logger()->info("Extension {$event->extension->name} was disabled");
200-
});
201-
```
202-
203-
## ⚙️ Configuration
204-
205-
Configure the package in `config/extensions.php`:
86+
## 📚 Documentation
20687

207-
```php
208-
return [
209-
// Extensions that cannot be disabled
210-
'protected' => [
211-
'Modules' => 'ExtensionsDebugger',
212-
],
213-
214-
// Loading order for active extensions
215-
'load_order' => [
216-
'Modules' => 'ExtensionsDebugger',
217-
],
218-
219-
// Mutually exclusive extension types
220-
'switch_types' => [
221-
'Themes',
222-
],
223-
224-
// Extension directories by type
225-
'paths' => [
226-
'Modules' => base_path('extensions/Modules'),
227-
'Themes' => base_path('extensions/Themes'),
228-
],
229-
230-
// Stub configuration for scaffolding
231-
'stubs' => [
232-
'path' => null, // Use package stubs
233-
'default' => [
234-
'config', 'console', 'database', 'events',
235-
'exceptions', 'facades', 'helpers', 'http',
236-
'jobs', 'lang', 'listeners', 'models',
237-
'notifications', 'policies', 'resources',
238-
'routes', 'rules', 'services',
239-
],
240-
],
241-
242-
// Activator class for managing states
243-
'activator' => \Gigabait93\Extensions\Activators\FileActivator::class,
244-
245-
// JSON file path for FileActivator
246-
'json_file' => base_path('storage/extensions.json'),
247-
];
248-
```
88+
For detailed documentation, visit [https://gigabait93.github.io/laravel-extensions/](https://gigabait93.github.io/laravel-extensions/).
24989

25090
## 🧪 Testing
25191

252-
Run the test suite:
253-
25492
```bash
25593
composer test
256-
```
257-
258-
Run code style checks:
259-
260-
```bash
261-
composer cs-check
262-
```
263-
264-
Fix code style issues:
265-
266-
```bash
26794
composer cs-fix
268-
```
269-
270-
Run static analysis:
271-
272-
```bash
27395
composer phpstan
27496
```
27597

276-
## 📚 Documentation
277-
278-
For detailed documentation, visit [https://gigabait93.github.io/laravel-extensions/](https://gigabait93.github.io/laravel-extensions/).
279-
280-
The documentation covers:
281-
- Installation and configuration
282-
- Extension development
283-
- Manifest format reference
284-
- Event system
285-
- API reference
286-
- Best practices
287-
28898
## 🤝 Contributing
28999

290100
Contributions are welcome! Please feel free to submit a Pull Request.

docs/scaffolding.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,23 @@ Use the `ExtensionBuilder` to generate extensions programmatically:
1717
```php
1818
use Gigabait93\Extensions\Scaffolding\ExtensionBuilder;
1919

20-
$builder = ExtensionBuilder::make()
20+
// Get available extension types and stub groups
21+
$availableTypes = ExtensionBuilder::getAvailableTypes();
22+
$availableGroups = ExtensionBuilder::getAvailableStubGroups();
23+
24+
// Build extension
25+
$builder = app(ExtensionBuilder::class);
26+
$result = $builder
2127
->withType('Modules')
2228
->withName('Blog')
2329
->withBasePath(base_path('extensions'))
30+
->withGroups(['providers', 'config', 'routes'])
2431
->build();
2532

2633
// Check result
27-
if ($builder->isSuccess()) {
28-
echo "Extension created successfully!";
29-
}
34+
echo "Extension created at: " . $result['path'];
35+
echo "Namespace: " . $result['namespace'];
36+
echo "Files created: " . count($result['files']);
3037
```
3138

3239
### 🎨 Template Variables

src/Entities/Extension.php

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Gigabait93\Extensions\Facades\Extensions as ExtensionsFacade;
88
use Gigabait93\Extensions\Support\ManifestValue;
99
use Gigabait93\Extensions\Support\OpResult;
10+
use Gigabait93\Extensions\Support\PathResolver;
1011

1112
/**
1213
* Extension entity that exposes all manifest fields as real, typed, read-only properties.
@@ -398,11 +399,7 @@ public function hasProviderFile(): bool
398399
return false;
399400
}
400401

401-
// Convert namespace to path
402-
$providerPath = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $this->provider) . '.php';
403-
$fullPath = $this->path . DIRECTORY_SEPARATOR . $providerPath;
404-
405-
return file_exists($fullPath);
402+
return PathResolver::hasProviderFile($this->path, $this->provider);
406403
}
407404

408405
public function getSize(): int
@@ -437,27 +434,17 @@ public function getFormattedSize(): string
437434

438435
public function hasReadme(): bool
439436
{
440-
$readmeFiles = ['README.md', 'readme.md', 'README.txt', 'readme.txt'];
441-
foreach ($readmeFiles as $file) {
442-
if (file_exists($this->path . DIRECTORY_SEPARATOR . $file)) {
443-
return true;
444-
}
445-
}
446-
447-
return false;
437+
return PathResolver::findReadmePath($this->path) !== null;
448438
}
449439

450440
public function getReadmeContent(): ?string
451441
{
452-
$readmeFiles = ['README.md', 'readme.md', 'README.txt', 'readme.txt'];
453-
foreach ($readmeFiles as $file) {
454-
$path = $this->path . DIRECTORY_SEPARATOR . $file;
455-
if (file_exists($path)) {
456-
return file_get_contents($path) ?: null;
457-
}
442+
$readmePath = PathResolver::findReadmePath($this->path);
443+
if ($readmePath === null) {
444+
return null;
458445
}
459446

460-
return null;
447+
return file_get_contents($readmePath) ?: null;
461448
}
462449

463450
public function compareVersion(string $version): int

src/Scaffolding/ExtensionBuilder.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,4 +234,29 @@ private function registryCanonicalName(string $type): string
234234

235235
return $type;
236236
}
237+
238+
/**
239+
* Get all available extension types from the registry.
240+
*
241+
* @return string[]
242+
*/
243+
public static function getAvailableTypes(): array
244+
{
245+
$registry = app(RegistryService::class);
246+
247+
return $registry->types();
248+
}
249+
250+
/**
251+
* Get all available stub groups from the default stubs path.
252+
*
253+
* @param string|null $stubsPath Optional custom stubs path
254+
* @return string[]
255+
*/
256+
public static function getAvailableStubGroups(?string $stubsPath = null): array
257+
{
258+
$path = $stubsPath ?? ScaffoldConfig::stubsPath();
259+
260+
return StubGroups::scan($path);
261+
}
237262
}

0 commit comments

Comments
 (0)