- Added a file input for PDF uploads with validation for file type and size. - Implemented file size formatting and user feedback for selected files. - Created upload and cancel methods with placeholder for future API integration. feat: Create PaymentForm.vue for handling payments - Developed a form for entering payment details including date, amount, method, and notes. - Integrated currency formatting and dropdown for payment methods. - Implemented save and cancel actions with API call for saving payment data. docs: Add documentation for dynamic plugin menus and permissions - Provided guidelines for defining menu items and permissions in plugins. - Explained the process for synchronizing permissions and integrating menus in the frontend. - Included examples and best practices for plugin development. feat: Add database migrations for invoices, invoice items, and payments - Created migration scripts to define the database schema for invoices, invoice items, and payments. - Established foreign key relationships between invoices and related entities. feat: Implement command for synchronizing plugin permissions - Developed a console command to synchronize plugin permissions with the database. - Added options for dry-run and force synchronization for unlicensed modules. feat: Create API controller for plugin menu items - Implemented API endpoints to retrieve plugin menu items in both flat and grouped formats. - Ensured access control with role-based permissions for API access. feat: Develop service for managing plugin menu items - Created a service to collect and manage menu items from installed plugins. - Implemented methods for retrieving flat and grouped menu items for frontend use. feat: Add service for synchronizing plugin permissions - Developed a service to handle the synchronization of plugin permissions with the database. - Included logic for creating and updating permission modules based on plugin definitions.
522 lines
11 KiB
Markdown
522 lines
11 KiB
Markdown
# Plugin-Menüs und Permissions
|
|
|
|
Anleitung zur dynamischen Registrierung von Menü-Items und Permissions durch Plugins.
|
|
|
|
## Übersicht
|
|
|
|
Das Plugin-System unterstützt jetzt:
|
|
|
|
✅ **Dynamische Menü-Items** - Plugins können eigene Menüpunkte hinzufügen
|
|
✅ **Automatische Permission-Synchronisation** - Modul-Permissions werden automatisch in der DB angelegt
|
|
✅ **Permission-basierte Sichtbarkeit** - Menüpunkte erscheinen nur für berechtigte User
|
|
✅ **Gruppierung** - Plugin-Menüs können gruppiert werden
|
|
|
|
---
|
|
|
|
## 1. Menü-Items im Plugin definieren
|
|
|
|
### In deiner Plugin-Klasse:
|
|
|
|
```php
|
|
public function getMenuItems(): array
|
|
{
|
|
return [
|
|
[
|
|
'label' => 'Rechnungen', // Menü-Titel
|
|
'icon' => 'pi-file-pdf', // PrimeIcons Icon (ohne pi pi-fw prefix)
|
|
'group' => 'Finanzen', // Gruppierung im Menü
|
|
'items' => [
|
|
[
|
|
'label' => 'Alle Rechnungen',
|
|
'icon' => 'pi-list',
|
|
'to' => '/billing/invoices', // Vue Router path
|
|
'permission' => 'billing.view' // Optional: Permission-Check
|
|
],
|
|
[
|
|
'label' => 'Neue Rechnung',
|
|
'icon' => 'pi-plus',
|
|
'to' => '/billing/invoices/create',
|
|
'permission' => 'billing.create'
|
|
],
|
|
[
|
|
'separator' => true // Optional: Trennlinie
|
|
],
|
|
[
|
|
'label' => 'Einstellungen',
|
|
'icon' => 'pi-cog',
|
|
'to' => '/billing/settings',
|
|
'permission' => 'billing.manage'
|
|
]
|
|
]
|
|
]
|
|
];
|
|
}
|
|
```
|
|
|
|
### Menü-Item Optionen:
|
|
|
|
| Feld | Typ | Required | Beschreibung |
|
|
|------|-----|----------|--------------|
|
|
| `label` | string | ✅ | Anzeigename des Menüpunkts |
|
|
| `icon` | string | ❌ | PrimeIcons Icon (ohne `pi pi-fw` prefix) |
|
|
| `to` | string | ❌ | Vue Router path |
|
|
| `url` | string | ❌ | Externe URL (alternativ zu `to`) |
|
|
| `items` | array | ❌ | Sub-Menüpunkte |
|
|
| `permission` | string | ❌ | Permission-String für Sichtbarkeits-Check |
|
|
| `group` | string | ❌ | Gruppierung im Hauptmenü |
|
|
| `separator` | bool | ❌ | Trennlinie (nur in Sub-Items) |
|
|
|
|
---
|
|
|
|
## 2. Permissions definieren
|
|
|
|
### In deiner Plugin-Klasse:
|
|
|
|
```php
|
|
public function getPermissionModules(): array
|
|
{
|
|
return ['billing', 'invoicing'];
|
|
}
|
|
```
|
|
|
|
Das System erstellt automatisch folgende Permissions:
|
|
- `billing.view`
|
|
- `billing.create`
|
|
- `billing.edit`
|
|
- `billing.delete`
|
|
- `billing.export`
|
|
- `billing.manage`
|
|
|
|
### Permission-Synchronisation durchführen:
|
|
|
|
```bash
|
|
# Alle Plugins synchronisieren
|
|
php bin/console app:plugin:sync-permissions
|
|
|
|
# Nur ein bestimmtes Plugin
|
|
php bin/console app:plugin:sync-permissions billing
|
|
|
|
# Dry-Run (zeigt nur was passieren würde)
|
|
php bin/console app:plugin:sync-permissions --dry-run
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
Plugin Permission-Module Synchronisation
|
|
========================================
|
|
|
|
Synchronisiere alle Plugins...
|
|
------------------------------
|
|
|
|
Aktion Anzahl
|
|
Neu erstellt 2
|
|
Aktualisiert 0
|
|
Übersprungen 5
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Frontend Integration
|
|
|
|
### API-Endpoints:
|
|
|
|
#### GET /api/plugin-menu
|
|
Gibt alle Plugin-Menü-Items als flache Liste zurück.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": [
|
|
{
|
|
"label": "Alle Rechnungen",
|
|
"icon": "pi-list",
|
|
"to": "/billing/invoices",
|
|
"permission": "billing.view",
|
|
"source": "billing"
|
|
}
|
|
],
|
|
"count": 1
|
|
}
|
|
```
|
|
|
|
#### GET /api/plugin-menu/grouped
|
|
Gibt gruppierte Plugin-Menü-Items zurück.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"Finanzen": [
|
|
{
|
|
"label": "Rechnungen",
|
|
"icon": "pi-file-pdf",
|
|
"items": [...]
|
|
}
|
|
]
|
|
},
|
|
"groups": ["Finanzen"]
|
|
}
|
|
```
|
|
|
|
### AppMenu.vue
|
|
|
|
Das Menü lädt automatisch Plugin-Menüs beim Mount:
|
|
|
|
```vue
|
|
<script setup>
|
|
import { ref, onMounted } from 'vue';
|
|
|
|
const model = ref([...coreMenu]);
|
|
|
|
const loadPluginMenus = async () => {
|
|
const response = await fetch('/api/plugin-menu/grouped');
|
|
const data = await response.json();
|
|
|
|
// Plugin-Menüs werden automatisch hinzugefügt
|
|
// Permission-Checks werden automatisch durchgeführt
|
|
};
|
|
|
|
onMounted(() => {
|
|
loadPluginMenus();
|
|
});
|
|
</script>
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Permission-Checks im Frontend
|
|
|
|
### Mit Composition API:
|
|
|
|
```vue
|
|
<script setup>
|
|
import { useAuthStore } from '@/stores/auth';
|
|
|
|
const authStore = useAuthStore();
|
|
|
|
// Permission prüfen
|
|
const canViewInvoices = authStore.hasPermission('billing.view');
|
|
</script>
|
|
|
|
<template>
|
|
<Button v-if="canViewInvoices" label="Rechnung anzeigen" />
|
|
</template>
|
|
```
|
|
|
|
### Im Template:
|
|
|
|
```vue
|
|
<template>
|
|
<div v-if="authStore.hasPermission('billing.create')">
|
|
<Button label="Neue Rechnung" @click="createInvoice" />
|
|
</div>
|
|
</template>
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Beispiel: Vollständiges Plugin
|
|
|
|
### BillingModulePlugin.php
|
|
|
|
```php
|
|
<?php
|
|
|
|
namespace MyCRM\BillingModule;
|
|
|
|
use App\Plugin\LicenseValidatorInterface;
|
|
use App\Plugin\ModulePluginInterface;
|
|
|
|
class BillingModulePlugin implements ModulePluginInterface
|
|
{
|
|
public function __construct(
|
|
private readonly LicenseValidatorInterface $licenseValidator
|
|
) {}
|
|
|
|
public function getIdentifier(): string
|
|
{
|
|
return 'billing';
|
|
}
|
|
|
|
public function getDisplayName(): string
|
|
{
|
|
return 'Rechnungsmodul';
|
|
}
|
|
|
|
public function getVersion(): string
|
|
{
|
|
return '1.0.0';
|
|
}
|
|
|
|
public function getDescription(): string
|
|
{
|
|
return 'Verwaltung von Rechnungen, Angeboten und Zahlungen';
|
|
}
|
|
|
|
public function isLicensed(): bool
|
|
{
|
|
return $this->licenseValidator->validate('billing')['valid'];
|
|
}
|
|
|
|
public function getLicenseInfo(): array
|
|
{
|
|
return $this->licenseValidator->validate('billing');
|
|
}
|
|
|
|
public function boot(): void
|
|
{
|
|
if (!$this->isLicensed()) {
|
|
throw new \RuntimeException('Billing Module nicht lizenziert');
|
|
}
|
|
|
|
// Services, Routes, etc. registrieren
|
|
}
|
|
|
|
public function getPermissionModules(): array
|
|
{
|
|
return ['billing', 'invoicing', 'payments'];
|
|
}
|
|
|
|
public function getMenuItems(): array
|
|
{
|
|
return [
|
|
[
|
|
'label' => 'Rechnungen',
|
|
'icon' => 'pi-file-pdf',
|
|
'group' => 'Finanzen',
|
|
'items' => [
|
|
[
|
|
'label' => 'Dashboard',
|
|
'icon' => 'pi-chart-line',
|
|
'to' => '/billing/dashboard',
|
|
'permission' => 'billing.view'
|
|
],
|
|
[
|
|
'label' => 'Alle Rechnungen',
|
|
'icon' => 'pi-list',
|
|
'to' => '/billing/invoices',
|
|
'permission' => 'billing.view'
|
|
],
|
|
[
|
|
'label' => 'Neue Rechnung',
|
|
'icon' => 'pi-plus',
|
|
'to' => '/billing/invoices/create',
|
|
'permission' => 'billing.create'
|
|
],
|
|
[
|
|
'separator' => true
|
|
],
|
|
[
|
|
'label' => 'Zahlungen',
|
|
'icon' => 'pi-money-bill',
|
|
'to' => '/billing/payments',
|
|
'permission' => 'payments.view'
|
|
],
|
|
[
|
|
'label' => 'Einstellungen',
|
|
'icon' => 'pi-cog',
|
|
'to' => '/billing/settings',
|
|
'permission' => 'billing.manage'
|
|
]
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
public function canInstall(): array
|
|
{
|
|
$errors = [];
|
|
|
|
if (PHP_VERSION_ID < 80200) {
|
|
$errors[] = 'PHP 8.2+ erforderlich';
|
|
}
|
|
|
|
return [
|
|
'success' => empty($errors),
|
|
'errors' => $errors
|
|
];
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 6. Workflow: Neues Plugin mit Menüs
|
|
|
|
### Schritt 1: Plugin erstellen
|
|
|
|
```bash
|
|
cd ../mycrm-billing-module
|
|
composer init
|
|
# Name: mycrm/billing-module
|
|
```
|
|
|
|
### Schritt 2: Plugin-Klasse implementieren
|
|
|
|
Siehe Beispiel oben - implementiere `getMenuItems()` und `getPermissionModules()`.
|
|
|
|
### Schritt 3: In myCRM installieren
|
|
|
|
```bash
|
|
cd ../myCRM
|
|
composer config repositories.mycrm-billing-module path ../mycrm-billing-module
|
|
composer require mycrm/billing-module:@dev
|
|
```
|
|
|
|
### Schritt 4: Permissions synchronisieren
|
|
|
|
```bash
|
|
php bin/console app:plugin:sync-permissions billing
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
Neu erstellt: 3 (billing, invoicing, payments)
|
|
```
|
|
|
|
### Schritt 5: Cache leeren
|
|
|
|
```bash
|
|
php bin/console cache:clear
|
|
```
|
|
|
|
### Schritt 6: Lizenz aktivieren
|
|
|
|
```bash
|
|
php bin/console app:module:license billing YOUR_GITEA_TOKEN
|
|
```
|
|
|
|
### Schritt 7: Testen
|
|
|
|
1. Frontend öffnen
|
|
2. Plugin-Menü erscheint unter "Finanzen"
|
|
3. Menüpunkte sind nur sichtbar mit Berechtigung
|
|
|
|
---
|
|
|
|
## 7. Debugging
|
|
|
|
### Menü-Items überprüfen:
|
|
|
|
```bash
|
|
curl http://localhost:8000/api/plugin-menu | jq
|
|
```
|
|
|
|
### Permissions in DB überprüfen:
|
|
|
|
```sql
|
|
SELECT * FROM modules WHERE code IN ('billing', 'invoicing', 'payments');
|
|
```
|
|
|
|
### Plugin-Status:
|
|
|
|
```bash
|
|
php bin/console app:module:list
|
|
```
|
|
|
|
### Logs:
|
|
|
|
```bash
|
|
tail -f var/log/dev.log | grep -E "(Plugin|Menu|Permission)"
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Best Practices
|
|
|
|
### ✅ DO's:
|
|
|
|
- **Gruppiere verwandte Menüs** - Nutze `group` für bessere Organisation
|
|
- **Permission-Checks** - Definiere `permission` für alle sensiblen Menüpunkte
|
|
- **Icons verwenden** - Macht das Menü übersichtlicher
|
|
- **Synchronisiere nach Installation** - `app:plugin:sync-permissions` nach jedem Plugin-Update
|
|
|
|
### ❌ DON'Ts:
|
|
|
|
- **Keine Core-Gruppen überschreiben** - "Home", "CRM", "Administration" sind reserviert
|
|
- **Keine tiefen Verschachtelungen** - Max. 2 Ebenen (Gruppe → Items)
|
|
- **Keine externen URLs ohne Warnung** - User erwarten interne Navigation
|
|
|
|
---
|
|
|
|
## 9. Troubleshooting
|
|
|
|
### Problem: Menü erscheint nicht
|
|
|
|
**Lösung:**
|
|
```bash
|
|
# Cache leeren
|
|
php bin/console cache:clear
|
|
|
|
# Plugin-Status prüfen
|
|
php bin/console app:module:list
|
|
|
|
# API testen
|
|
curl http://localhost:8000/api/plugin-menu/grouped
|
|
|
|
# Browser-Console überprüfen
|
|
```
|
|
|
|
### Problem: Permissions fehlen
|
|
|
|
**Lösung:**
|
|
```bash
|
|
# Permissions synchronisieren
|
|
php bin/console app:plugin:sync-permissions
|
|
|
|
# DB überprüfen
|
|
SELECT * FROM modules WHERE code = 'billing';
|
|
|
|
# Rolle zuweisen
|
|
# In der Rollenverwaltung das neue Modul auswählen
|
|
```
|
|
|
|
### Problem: Permission-Checks funktionieren nicht
|
|
|
|
**Lösung:**
|
|
- Prüfe ob User die Rolle hat
|
|
- Prüfe ob Rolle die Permission hat
|
|
- Prüfe `authStore.hasPermission()` Implementierung
|
|
|
|
---
|
|
|
|
## 10. Migration bestehender Plugins
|
|
|
|
Wenn du bereits Plugins hast, füge einfach `getMenuItems()` hinzu:
|
|
|
|
```php
|
|
// Altes Plugin
|
|
class MyPlugin implements ModulePluginInterface {
|
|
// ... bestehende Methoden ...
|
|
}
|
|
|
|
// Neu: Füge hinzu
|
|
class MyPlugin implements ModulePluginInterface {
|
|
// ... bestehende Methoden ...
|
|
|
|
public function getMenuItems(): array
|
|
{
|
|
return [
|
|
// Deine Menüs hier
|
|
];
|
|
}
|
|
}
|
|
```
|
|
|
|
Dann:
|
|
```bash
|
|
composer dump-autoload
|
|
php bin/console cache:clear
|
|
```
|
|
|
|
---
|
|
|
|
## Support
|
|
|
|
Bei Fragen siehe:
|
|
- `PLUGIN_SYSTEM.md` - Allgemeine Plugin-Architektur
|
|
- `GITEA_LICENSE_SYSTEM.md` - Lizenzierung
|
|
- `docs/PERMISSIONS.md` - Permission-System
|