Developer - Dateisystem-Synchronisation
Keywords: Developer, Sync, Synchronisation, Template, Modul, Action, Dateisystem, Git, Versionskontrolle, Console
Übersicht
Developer synchronisiert Templates, Module und Actions zwischen Datenbank und Dateisystem für die Arbeit mit externen Editoren und Git-Versionskontrolle.
Kern-Klassen
| Klasse | Beschreibung |
|---|---|
rex_developer_manager |
Manager für alle Synchronizer (Start/Register) |
rex_developer_synchronizer |
Abstract-Klasse für Sync-Implementierungen |
rex_developer_synchronizer_default |
Standard-Synchronizer für DB-Tabellen |
rex_developer_synchronizer_item |
Repräsentiert ein Sync-Item |
rex_developer_command |
Console-Command für CLI-Sync |
Manager-Methoden
| Methode | Rückgabe | Beschreibung |
|---|---|---|
rex_developer_manager::start($force) |
void | Startet Synchronisation |
rex_developer_manager::synchronize($type, $force) |
void | Führt Synchronisation aus |
rex_developer_manager::register($sync, $start) |
void | Registriert Synchronizer |
rex_developer_manager::setBasePath($path) |
void | Setzt Basis-Pfad |
rex_developer_manager::getBasePath() |
string | Gibt Basis-Pfad zurück |
Synchronizer-Item-Methoden
| Methode | Rückgabe | Beschreibung |
|---|---|---|
getId() |
int | Item-ID |
getName() |
string | Item-Name |
getUpdated() |
int | Timestamp der letzten Änderung |
getFiles() |
array | Alle Dateien mit Content |
getFile($file) |
string | Content einer Datei |
setFile($file, $content) |
void | Setzt Datei-Content |
Synchronizer-Force-Modi
| Konstante | Beschreibung |
|---|---|
rex_developer_synchronizer::FORCE_DB |
Datenbank überschreibt Dateien |
rex_developer_synchronizer::FORCE_FILES |
Dateien überschreiben Datenbank |
Praxisbeispiele
1. Standard-Ordnerstruktur
redaxo/data/addons/developer/
├── templates/
│ ├── Startseite [1]/
│ │ ├── 1.rex_id
│ │ ├── metadata.yml
│ │ └── template.php
│ └── Navigation [2]/
│ ├── 2.rex_id
│ ├── metadata.yml
│ └── template.php
├── modules/
│ ├── Hero Slider [10]/
│ │ ├── 10.rex_id
│ │ ├── metadata.yml
│ │ ├── input.php
│ │ └── output.php
│ └── Kontaktformular [11]/
│ ├── 11.rex_id
│ ├── metadata.yml
│ ├── input.php
│ └── output.php
└── actions/
└── SEO Meta Tags [5]/
├── 5.rex_id
├── metadata.yml
├── preview.php
├── presave.php
└── postsave.php
2. Template metadata.yml
name: Startseite
key: homepage
active: true
attributes:
ctype: []
ctypes:
- "1"
- "2"
categories:
- "1"
3. Modul metadata.yml
name: Hero Slider
key: hero_slider
4. Action metadata.yml
name: SEO Meta Tags
previewmode: 1
presavemode: 0
postsavemode: 1
5. Console-Command
php redaxo/bin/console developer:sync
# Synchronizes developer files.
6. Force DB (Dateien überschreiben)
php redaxo/bin/console developer:sync --force-db
7. Force Files (Datenbank überschreiben)
php redaxo/bin/console developer:sync --force-files
8. Eigenen Synchronizer registrieren
$synchronizer = new rex_developer_synchronizer_default(
'custom_table',
rex::getTable('my_custom'),
['content' => 'content.php'],
['status' => 'int', 'priority' => 'int']
);
rex_developer_manager::register($synchronizer);
9. Synchronizer mit Callback
$synchronizer = new rex_developer_synchronizer_default(
'modules',
rex::getTable('module'),
['input' => 'input.php', 'output' => 'output.php']
);
$synchronizer->setEditedCallback(function (rex_developer_synchronizer_item $item) {
// Alle Artikel mit diesem Modul aus Cache löschen
rex_article_cache::deleteAll();
});
$synchronizer->setDeletedCallback(function (rex_developer_synchronizer_item $item) {
// Log-Eintrag erstellen
rex_logger::factory()->log('developer', 'Module deleted: ' . $item->getName());
});
rex_developer_manager::register($synchronizer);
10. Custom Base Path
rex_developer_manager::setBasePath(rex_path::data('my_custom_path'));
11. Metadata-Spalten definieren
$synchronizer = new rex_developer_synchronizer_default(
'templates',
rex::getTable('template'),
['content' => 'template.php'],
[
'key' => 'string',
'active' => 'boolean',
'attributes' => 'json'
]
);
12. ID-Spalte anpassen
$synchronizer = new rex_developer_synchronizer_default(
'custom_table',
rex::getTable('my_table'),
['content' => 'content.php']
);
$synchronizer->setIdColumn('uid');
$synchronizer->setNameColumn('title');
$synchronizer->setUpdatedColumn('modified_at');
13. Extension Point DEVELOPER_MANAGER_START
rex_extension::register('DEVELOPER_MANAGER_START', function($ep) {
// Custom Synchronizer registrieren
$sync = new rex_developer_synchronizer_default(...);
rex_developer_manager::register($sync);
});
14. Template programmatisch erstellen
redaxo/data/addons/developer/templates/Custom Template [99]/
├── 99.rex_id
├── metadata.yml
└── template.php
metadata.yml:
name: Custom Template
key: custom
active: true
template.php:
<?php
echo '<h1>Custom Template</h1>';
15. Modul programmatisch erstellen
redaxo/data/addons/developer/modules/Dynamic Module [100]/
├── 100.rex_id
├── metadata.yml
├── input.php
└── output.php
16. Dateinamen mit Präfix
Backend-Einstellung: “Präfix aktivieren”
templates/
└── Startseite [1]/
├── 1.rex_id
├── metadata.yml
└── 1.Startseite.template.php
17. Custom Dateinamen
modules/Hero Slider [10]/
├── 10.rex_id
├── metadata.yml
├── hero-slider-backend.input.php
└── hero-slider-frontend.output.php
Developer erkennt *.input.php und *.output.php automatisch.
18. Ordner-Suffix mit ID
Backend-Einstellung: “ID-Suffix aktivieren”
templates/
├── Startseite [1]/
└── Navigation [2]/
19. Automatische Umbenennung deaktivieren
Backend-Einstellung: “Automatische Umbenennung” deaktivieren
Dann können Ordner beliebig umbenannt werden (Zuordnung über .rex_id):
modules/
└── my-custom-folder-name/
├── 10.rex_id
├── metadata.yml
├── input.php
└── output.php
20. Item aus Dateisystem löschen
Bei aktivierter Option “Ordner automatisch löschen”:
- Im Backend Module löschen
- Developer löscht Ordner automatisch
Bei deaktivierter Option:
- Im Backend Module löschen
.rex_idwird zu.rex_ignore- Ordner bleibt erhalten
21. Sync im Frontend deaktivieren
// config.yml oder boot.php
rex_addon::get('developer')->setConfig('sync_frontend', false);
22. Sync im Backend deaktivieren
rex_addon::get('developer')->setConfig('sync_backend', false);
23. YForm E-Mail Templates synchronisieren
Backend-Einstellung: “YForm E-Mail Templates synchronisieren” aktivieren
redaxo/data/addons/developer/yform_email/
└── Kontaktformular [1]/
├── 1.rex_id
├── metadata.yml
├── body.php
└── body_html.php
metadata.yml:
name: Kontaktformular
mail_from: noreply@example.com
mail_from_name: Website
subject: Neue Kontaktanfrage
24. Umlaute in Dateinamen
Backend-Einstellung: “Umlaute ersetzen” aktivieren
Ä → Ae
Ö → Oe
Ü → Ue
ß → ss
Deaktiviert: Umlaute bleiben erhalten.
25. Nach DB-Import synchronisieren
rex_extension::register('BACKUP_AFTER_DB_IMPORT', function() {
rex_developer_manager::synchronize(null, rex_developer_synchronizer::FORCE_DB);
});
26. Editor-URL für Templates/Module
rex_extension::register('EDITOR_URL', function(rex_extension_point $ep) {
// rex:///template/1/template
// rex:///module/10/input
$file = $ep->getParam('file');
$line = $ep->getParam('line');
// Developer generiert automatisch URL zum Editor
return rex_editor::factory()->getUrl($file, $line);
});
27. Eigene Synchronizer-Klasse
class my_custom_synchronizer extends rex_developer_synchronizer
{
protected function getItems()
{
$items = [];
$sql = rex_sql::factory();
$sql->setQuery('SELECT * FROM ' . rex::getTable('my_table'));
foreach ($sql as $row) {
$item = new rex_developer_synchronizer_item(
$row->getValue('id'),
$row->getValue('name'),
strtotime($row->getValue('updatedate'))
);
$item->setFile('content.php', $row->getValue('content'));
$items[] = $item;
}
return $items;
}
protected function addItem(rex_developer_synchronizer_item $item)
{
$sql = rex_sql::factory();
$sql->setTable(rex::getTable('my_table'));
$sql->setValue('name', $item->getName());
$sql->setValue('content', $item->getFile('content.php'));
$sql->setDateTimeValue('updatedate', $item->getUpdated());
$sql->insert();
return (int) $sql->getLastId();
}
protected function editItem(rex_developer_synchronizer_item $item)
{
$sql = rex_sql::factory();
$sql->setTable(rex::getTable('my_table'));
$sql->setWhere(['id' => $item->getId()]);
$sql->setValue('name', $item->getName());
$sql->setValue('content', $item->getFile('content.php'));
$sql->setDateTimeValue('updatedate', $item->getUpdated());
$sql->update();
}
protected function deleteItem(rex_developer_synchronizer_item $item)
{
$sql = rex_sql::factory();
$sql->setTable(rex::getTable('my_table'));
$sql->setWhere(['id' => $item->getId()]);
$sql->delete();
}
}
// Registrieren
$sync = new my_custom_synchronizer('my_custom', ['content.php']);
rex_developer_manager::register($sync);
28. Datei-Content lazy laden
$item = new rex_developer_synchronizer_item(1, 'Example', time());
// Callable statt String für große Dateien
$item->setFile('template.php', function() {
return rex_file::get(rex_path::frontend('large-template.php'));
});
29. Serialize/JSON Metadata
$synchronizer = new rex_developer_synchronizer_default(
'custom',
rex::getTable('my_table'),
['content' => 'content.php'],
[
'config' => 'json', // JSON-Objekt
'settings' => 'serialize', // PHP-Serialized
'active' => 'boolean',
'priority' => 'int'
]
);
metadata.yml:
name: Example
config:
option1: value1
option2: value2
settings: 'a:2:{s:3:"foo";s:3:"bar";s:3:"baz";i:42;}'
active: true
priority: 10
30. Debug-Modus Synchronisation
// Frontend-Sync nur mit aktivem Debug-Modus
if (rex::isDebugMode() || rex_backend_login::createUser()->isAdmin()) {
rex_developer_manager::start();
}
Integration: Developer arbeitet mit Structure/Content-Plugin (Templates/Module/Actions), YForm (E-Mail-Templates), Console (CLI-Commands), Backup-Addon (FORCE_DB nach Import), Editor-Integration (URL-Generator), Extension Points (DEVELOPER_MANAGER_START, BACKUP_AFTER_DB_IMPORT, EDITOR_URL) und Git-Workflows (Versionskontrolle). Synchronisation erfolgt bei aktiviertem Backend/Frontend-Login und berücksichtigt Timestamps für Konflikt-Erkennung.