YForm - Formular-Builder & ORM
Keywords: Form Builder ORM Database Table Manager Dataset Query Frontend Backend Validation CRUD YOrm
Übersicht
Universelles Formular- und Datenbank-Management-System mit ORM (YOrm), Table Manager für Backend-CRUD, Frontend-Formularen und E-Mail-Versand.
Kern-Klassen
rex_yform_manager_table
| Methode | Parameter | Rückgabe | Beschreibung |
|---|---|---|---|
::get($tableName) |
string | rex_yform_manager_table|null | Lädt Table-Definition |
::getAll() |
- | array | Alle registrierten Tabellen |
query() |
- | rex_yform_manager_query | Query-Builder für Tabelle |
getCSRFKey() |
- | rex_csrf_token | CSRF-Token für Tabelle |
getRawValues() |
- | array | Alle Felder der Tabelle |
getFields() |
- | array | Feld-Objekte |
getName() |
- | string | Tabellenname (z.B. ‘rex_my_table’) |
::deleteCache() |
- | void | Table-Cache löschen |
rex_yform_manager_dataset
| Methode | Parameter | Rückgabe | Beschreibung |
|---|---|---|---|
::get($id, $table) |
int, string | rex_yform_manager_dataset|null | Lädt Datensatz per ID |
::create($table) |
string | rex_yform_manager_dataset | Neuer leerer Datensatz |
::query() |
- | rex_yform_manager_query | Query-Builder (statisch) |
getValue($key, $default) |
string, mixed | mixed | Feld-Wert abrufen |
setValue($key, $value) |
string, mixed | $this | Feld-Wert setzen |
save() |
- | bool | Speichert Datensatz (Insert/Update) |
delete() |
- | bool | Löscht Datensatz |
getMessages() |
- | array | Validierungs-Fehler |
getId() |
- | int | Primary Key |
getRelatedDataset($key) |
string | rex_yform_manager_dataset|null | Relation folgen |
getRelatedCollection($key) |
string | rex_yform_manager_collection | 1:n Relation |
getForm() |
- | rex_yform | YForm-Formular für Datensatz |
executeForm($yform) |
rex_yform | string | Formular ausführen & ausgeben |
::setModelClass($table, $class) |
string, string | void | Custom Model registrieren |
rex_yform_manager_query
| Methode | Parameter | Rückgabe | Beschreibung |
|---|---|---|---|
find() |
- | rex_yform_manager_collection | Alle Ergebnisse |
findOne() |
- | rex_yform_manager_dataset|null | Erstes Ergebnis |
findId($id) |
int | rex_yform_manager_dataset|null | Per ID suchen |
where($column, $value, $operator) |
string, mixed, string | $this | WHERE-Bedingung |
whereRaw($sql, $params) |
string, array | $this | Raw SQL WHERE |
orderBy($column, $direction) |
string, string | $this | ORDER BY |
limit($limit, $offset) |
int, int | $this | LIMIT |
alias($alias) |
string | $this | Tabellen-Alias |
joinRelation($field, $alias) |
string, string | $this | JOIN über Relation |
select($field, $alias) |
string, string | $this | Spalte auswählen |
selectRaw($sql) |
string | $this | Raw SQL SELECT |
count() |
- | int | Anzahl Ergebnisse |
exists() |
- | bool | Mindestens 1 Ergebnis? |
chunk($size, $callback) |
int, callable | void | Batch-Processing |
paginate($page, $perPage) |
int, int | array | Pagination-Daten |
rex_yform
| Methode | Parameter | Rückgabe | Beschreibung |
|---|---|---|---|
::factory() |
- | rex_yform | Neues Formular |
setObjectparams($key, $value) |
string, mixed | void | Parameter setzen (form_action, form_method) |
setValueField($type, $params) |
string, array | void | Value-Feld hinzufügen (text, textarea, select) |
setValidateField($type, $params) |
string, array | void | Validation hinzufügen |
setActionField($type, $params) |
string, array | void | Action (db, email, showtext) |
getForm() |
- | string | Rendert Formular-HTML |
::addTemplatePath($path) |
string | void | Template-Verzeichnis registrieren |
Praxisbeispiele
Table Manager - Tabelle abrufen
// Tabelle laden
$table = rex_yform_manager_table::get('rex_my_products');
echo $table->getName(); // 'rex_my_products'
// Alle Felder
foreach ($table->getFields() as $field) {
echo $field->getName() . ' - ' . $field->getTypeName();
}
// CSRF-Token für Frontend-Formulare
$token = $table->getCSRFKey();
Alle Tabellen auflisten
// Alle YForm-Tabellen
foreach (rex_yform_manager_table::getAll() as $table) {
echo $table->getName() . '<br>';
}
// Mit Feldanzahl
foreach (rex_yform_manager_table::getAll() as $table) {
echo $table->getName() . ': ' . count($table->getFields()) . ' Felder<br>';
}
Dataset abrufen
// Datensatz per ID
$product = rex_yform_manager_dataset::get(42, 'rex_products');
if ($product) {
echo $product->name;
echo $product->price;
echo $product->description;
}
// Mit Fallback
$product = rex_yform_manager_dataset::get($id, 'rex_products');
if (!$product) {
echo 'Produkt nicht gefunden';
exit;
}
Dataset erstellen & speichern
// Neuen Datensatz erstellen
$product = rex_yform_manager_dataset::create('rex_products');
$product->name = 'Neues Produkt';
$product->price = 99.90;
$product->description = 'Beschreibung...';
$product->status = 1;
if ($product->save()) {
echo 'Gespeichert mit ID: ' . $product->getId();
} else {
echo 'Fehler: ' . implode('<br>', $product->getMessages());
}
Dataset aktualisieren
// Bestehenden Datensatz laden und ändern
$product = rex_yform_manager_dataset::get(42, 'rex_products');
if ($product) {
$product->name = 'Geänderter Name';
$product->price = 149.90;
if ($product->save()) {
echo 'Aktualisiert';
} else {
echo 'Fehler: ' . implode('<br>', $product->getMessages());
}
}
Dataset löschen
// Datensatz löschen
$product = rex_yform_manager_dataset::get(42, 'rex_products');
if ($product && $product->delete()) {
echo 'Gelöscht';
} else {
echo 'Fehler beim Löschen';
}
// Oder direkt via Query
rex_yform_manager_dataset::query('rex_products')
->findId(42)
?->delete();
Custom Model Class
// In lib/Models/Product.php
class Product extends rex_yform_manager_dataset
{
// Eigene Methoden
public function getFormattedPrice()
{
return number_format($this->price, 2, ',', '.') . ' €';
}
public function isAvailable()
{
return $this->status == 1 && $this->stock > 0;
}
// Accessor (wird automatisch bei $product->full_name aufgerufen)
public function getFullName()
{
return $this->name . ' (' . $this->sku . ')';
}
}
// In boot.php registrieren
rex_yform_manager_dataset::setModelClass('rex_products', Product::class);
// Verwendung
$product = Product::query()->findId(42);
echo $product->getFormattedPrice(); // "99,90 €"
echo $product->full_name; // "Mein Produkt (SKU-123)" (via getFullName)
Query - Einfache Abfragen
// Alle Datensätze
$products = rex_yform_manager_dataset::query('rex_products')
->find();
foreach ($products as $product) {
echo $product->name;
}
// Mit WHERE
$products = rex_yform_manager_dataset::query('rex_products')
->where('status', 1)
->where('price', 100, '>')
->find();
// Mit ORDER BY und LIMIT
$products = rex_yform_manager_dataset::query('rex_products')
->where('status', 1)
->orderBy('name', 'ASC')
->limit(10)
->find();
Query - Komplexe Abfragen
// Mit Alias und JOIN
$products = rex_yform_manager_dataset::query('rex_products')
->alias('p')
->joinRelation('category_id', 'c') // Folgt Relation-Feld
->select('c.name', 'category_name')
->where('p.status', 1)
->orderBy('p.name')
->find();
foreach ($products as $product) {
echo $product->name . ' - ' . $product->category_name;
}
// Raw SQL
$products = rex_yform_manager_dataset::query('rex_products')
->whereRaw('LOWER(name) LIKE ?', ['%redaxo%'])
->selectRaw('COUNT(*) as total')
->find();
Query - Count & Exists
// Anzahl
$count = rex_yform_manager_dataset::query('rex_products')
->where('status', 1)
->count();
echo 'Aktive Produkte: ' . $count;
// Existiert?
$exists = rex_yform_manager_dataset::query('rex_products')
->where('sku', 'PROD-123')
->exists();
if ($exists) {
echo 'SKU bereits vergeben';
}
Query - Pagination
// Seite 1, 20 Einträge pro Seite
$page = rex_request::get('page', 'int', 1);
$result = rex_yform_manager_dataset::query('rex_products')
->where('status', 1)
->orderBy('name')
->paginate($page, 20);
// $result = ['items' => Collection, 'total' => int, 'page' => int, 'perPage' => int, 'pages' => int]
foreach ($result['items'] as $product) {
echo $product->name . '<br>';
}
// Pagination ausgeben
echo 'Seite ' . $result['page'] . ' von ' . $result['pages'];
echo ' (' . $result['total'] . ' gesamt)';
Query - Chunk Processing
// Große Datenmengen in Batches verarbeiten
rex_yform_manager_dataset::query('rex_products')
->chunk(100, function($products) {
foreach ($products as $product) {
// Verarbeitung
$product->processHeavyOperation();
}
});
Relationen - belongsTo (n:1)
// Produkt hat eine Kategorie (category_id Relation-Feld)
$product = rex_yform_manager_dataset::get(42, 'rex_products');
// Kategorie laden
$category = $product->getRelatedDataset('category_id');
if ($category) {
echo $category->name;
}
// Oder direkt via JOIN
$product = rex_yform_manager_dataset::query('rex_products')
->joinRelation('category_id', 'c')
->select('c.name', 'category_name')
->findId(42);
echo $product->category_name;
Relationen - hasMany (1:n)
// Kategorie hat viele Produkte
$category = rex_yform_manager_dataset::get(5, 'rex_categories');
// Alle Produkte der Kategorie
$products = $category->getRelatedCollection('category_id', 'rex_products');
foreach ($products as $product) {
echo $product->name;
}
// Mit Filter
$products = rex_yform_manager_dataset::query('rex_products')
->where('category_id', $category->id)
->where('status', 1)
->orderBy('name')
->find();
Frontend-Formular (Pipe-Notation)
// In Modul-Ausgabe
$yform = rex_yform::factory();
// Formular-Parameter
$yform->setObjectparams('form_action', rex_getUrl());
$yform->setObjectparams('form_method', 'post');
$yform->setObjectparams('form_showformafterupdate', 0);
// Felder (Pipe-Notation)
$yform->setValueField('text', ['name', 'Name*']);
$yform->setValueField('text', ['email', 'E-Mail*']);
$yform->setValueField('textarea', ['message', 'Nachricht*']);
// Validierung
$yform->setValidateField('empty', ['name', 'Bitte Namen angeben']);
$yform->setValidateField('empty', ['email', 'Bitte E-Mail angeben']);
$yform->setValidateField('email', ['email', 'Ungültige E-Mail']);
// Aktion: E-Mail senden
$yform->setActionField('email', [
'empfänger@example.com',
'Kontaktformular',
'Name: ###name###\nE-Mail: ###email###\nNachricht:\n###message###'
]);
// Erfolgs-Meldung
$yform->setActionField('showtext', ['', 'Vielen Dank für Ihre Nachricht!']);
// Ausgabe
echo $yform->getForm();
Frontend-Formular (PHP-API)
$yform = rex_yform::factory();
$yform->setObjectparams('form_action', rex_getUrl());
// Text-Feld
$yform->setValueField('text', [
'name' => 'name',
'label' => 'Name',
'notice' => 'Ihr vollständiger Name'
]);
// Select mit Optionen
$yform->setValueField('select', [
'name' => 'category',
'label' => 'Kategorie',
'options' => 'Allgemein,Support,Vertrieb'
]);
// Checkbox
$yform->setValueField('checkbox', [
'name' => 'newsletter',
'label' => 'Newsletter abonnieren'
]);
echo $yform->getForm();
Frontend-Formular in DB speichern
$yform = rex_yform::factory();
$yform->setObjectparams('form_action', rex_getUrl());
// Felder
$yform->setValueField('text', ['name', 'Name*']);
$yform->setValueField('text', ['email', 'E-Mail*']);
$yform->setValueField('textarea', ['message', 'Nachricht*']);
// Validierung
$yform->setValidateField('empty', ['name', 'Pflichtfeld']);
$yform->setValidateField('email', ['email', 'Ungültige E-Mail']);
// In DB speichern (rex_contact_messages)
$yform->setActionField('db', [
'rex_contact_messages', // Tabellenname
'name,email,message,createdate', // Felder
'', // Main-ID (leer = INSERT)
'', // DB-Feld für Main-ID
'', // Hidden-Felder
'', // Auto-Felder (z.B. createdate=NOW())
]);
// Erfolgs-Meldung
$yform->setActionField('showtext', ['', 'Nachricht gespeichert!']);
echo $yform->getForm();
Dataset-Formular im Frontend
// Bestehenden Datensatz bearbeiten
$product = rex_yform_manager_dataset::get($id, 'rex_products');
if ($product) {
// Formular aus Dataset generieren
$yform = $product->getForm();
// Parameter anpassen
$yform->setObjectparams('form_action', rex_getUrl(REX_ARTICLE_ID, '', ['id' => $id]));
$yform->setObjectparams('form_method', 'post');
$yform->setObjectparams('getdata', true); // Daten laden
// Erfolgs-Meldung
$yform->setActionField('showtext', ['', 'Produkt aktualisiert']);
// Ausgabe
echo $product->executeForm($yform);
}
Neuen Datensatz via Frontend-Formular
// Neuen Datensatz erstellen
$product = rex_yform_manager_dataset::create('rex_products');
// Formular generieren
$yform = $product->getForm();
$yform->setObjectparams('form_action', rex_getUrl());
$yform->setActionField('showtext', ['', 'Produkt erstellt!']);
// Ausgabe
echo $product->executeForm($yform);
Custom Templates
// Custom Template-Pfad registrieren (boot.php)
rex_yform::addTemplatePath(rex_path::addon('project', 'ytemplates'));
// Template-Struktur:
// project/ytemplates/
// bootstrap/
// value.text.tpl.php
// value.textarea.tpl.php
// foundation/
// ...
// Im Formular Template setzen
$yform->setObjectparams('form_ytemplate', 'bootstrap');
E-Mail-Versand mit Anhang
$yform = rex_yform::factory();
$yform->setObjectparams('form_action', rex_getUrl());
// Felder
$yform->setValueField('text', ['name', 'Name']);
$yform->setValueField('text', ['email', 'E-Mail']);
$yform->setValueField('upload', ['attachment', 'Anhang', '', '', 1]); // 1 = erforderlich
// E-Mail mit Anhang
$yform->setActionField('email', [
'empfänger@example.com', // An
'Kontakt mit Anhang', // Betreff
'Name: ###name###\nE-Mail: ###email###', // Body
'', // Von (leer = aus Config)
'', // Von-Name
'', // Reply-To
'', // BCC
'', // CC
'', // Anhänge-Feld: attachment
'attachment'
]);
echo $yform->getForm();
Validierung - Komplexe Regeln
$yform = rex_yform::factory();
// Pflichtfeld
$yform->setValidateField('empty', ['name', 'Name ist Pflicht']);
// E-Mail
$yform->setValidateField('email', ['email', 'Ungültige E-Mail']);
// Länge (min, max)
$yform->setValidateField('type', ['password', 'string', 'Passwort muss Text sein']);
$yform->setValidateField('compare_value', ['password', '>=', 8, 'Mindestens 8 Zeichen']);
// RegEx
$yform->setValidateField('preg_match', ['phone', '/^[0-9\s\-\+]+$/', 'Nur Zahlen, Leerzeichen, +, -']);
// Custom Validation
$yform->setValidateField('customfunction', [
'email',
'myCustomValidator',
'',
'E-Mail bereits registriert'
]);
// In lib/functions.php
function myCustomValidator($email, $params) {
$exists = rex_yform_manager_dataset::query('rex_users')
->where('email', $email)
->exists();
return !$exists; // true = valid, false = invalid
}
Datensatz-Events
// In Custom Model Class
class Product extends rex_yform_manager_dataset
{
// Before Save
public function preSave()
{
// Slug generieren
if (empty($this->slug)) {
$this->slug = rex_string::normalize($this->name);
}
// Timestamps
if (!$this->getId()) {
$this->created_at = date('Y-m-d H:i:s');
}
$this->updated_at = date('Y-m-d H:i:s');
}
// After Save
public function postSave()
{
// Cache löschen
rex_delete_cache();
// Benachrichtigung
if ($this->wasModified('status') && $this->status == 1) {
$this->sendPublishNotification();
}
}
// Before Delete
public function preDelete()
{
// Beziehungen löschen
rex_sql::factory()
->setTable('rex_product_images')
->setWhere(['product_id' => $this->id])
->delete();
}
}
Mass Operations
// Mehrere Datensätze auf einmal aktualisieren
$products = rex_yform_manager_dataset::query('rex_products')
->where('category_id', 5)
->find();
foreach ($products as $product) {
$product->status = 0;
$product->save();
}
// Oder via SQL (schneller für große Mengen)
rex_sql::factory()
->setTable('rex_products')
->setWhere(['category_id' => 5])
->setValue('status', 0)
->update();
Soft Deletes
// In Custom Model mit deleted_at Feld
class Product extends rex_yform_manager_dataset
{
// Überschreibe delete()
public function delete()
{
$this->deleted_at = date('Y-m-d H:i:s');
return $this->save();
}
// Query-Scope für nur aktive
public static function active()
{
return static::query()
->whereRaw('deleted_at IS NULL');
}
// Wiederherstellen
public function restore()
{
$this->deleted_at = null;
return $this->save();
}
}
// Verwendung
$products = Product::active()->find(); // Nur nicht-gelöschte
Export nach CSV
// Datensätze exportieren
$products = rex_yform_manager_dataset::query('rex_products')
->where('status', 1)
->orderBy('name')
->find();
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="products.csv"');
$fp = fopen('php://output', 'w');
// Header
fputcsv($fp, ['ID', 'Name', 'Price', 'SKU'], ';');
// Daten
foreach ($products as $product) {
fputcsv($fp, [
$product->id,
$product->name,
$product->price,
$product->sku
], ';');
}
fclose($fp);
exit;
Import aus CSV
// CSV importieren
$file = $_FILES['import']['tmp_name'];
if (($handle = fopen($file, 'r')) !== false) {
// Header überspringen
fgetcsv($handle, 1000, ';');
while (($data = fgetcsv($handle, 1000, ';')) !== false) {
$product = rex_yform_manager_dataset::create('rex_products');
$product->name = $data[0];
$product->price = $data[1];
$product->sku = $data[2];
$product->status = 1;
if (!$product->save()) {
echo 'Fehler: ' . implode(', ', $product->getMessages());
}
}
fclose($handle);
echo 'Import abgeschlossen';
}
Table Cache löschen
// Nach Schema-Änderungen Cache löschen
rex_yform_manager_table::deleteCache();
// Z.B. in update.php nach Tabellen-Änderungen
$addon = rex_addon::get('myAddon');
// Tabelle modifizieren
$sql = rex_sql::factory();
$sql->setQuery('ALTER TABLE rex_my_table ADD COLUMN new_field VARCHAR(255)');
// Cache löschen
rex_yform_manager_table::deleteCache();
JSON-Export
// Datensätze als JSON
$products = rex_yform_manager_dataset::query('rex_products')
->where('status', 1)
->find();
$data = [];
foreach ($products as $product) {
$data[] = [
'id' => $product->id,
'name' => $product->name,
'price' => $product->price,
'category' => $product->getRelatedDataset('category_id')->name ?? null
];
}
header('Content-Type: application/json');
echo json_encode($data, JSON_PRETTY_PRINT);
exit;
REST-API
Erste Schritte mit der REST-API
Die REST-API ermöglicht externen Zugriff auf YForm-Tabellen zum Abrufen, Erstellen, Aktualisieren und Löschen von Datensätzen. Die Klasse muss zunächst registriert werden (siehe YOrm), um REST-Zugriff zu ermöglichen. Alle Daten werden als JSON übertragen.
Hinweis: Die Tabellen müssen mit YForm verwaltbar sein, da diese Felder automatisch genutzt werden.
Die Schnittstelle orientiert sich an https://jsonapi.org/format/. Aufrufe und JSON-Formate sind ähnlich oder identisch aufgebaut.
Eine Video-Einführung aus der REDAXOHour erklärt viele Punkte dieses Kapitels.
Konfiguration / Endpoints
Der REST-Zugriff muss für jeden Endpoint einzeln definiert werden. Für jede Tabelle und jedes Nutzungsszenario ist eine eigene Konfiguration erforderlich.
Die Standard-Route der REST-API ist /rest. Unterhalb dieser Route können eigene Endpunkte definiert werden.
Die Konfiguration erfolgt über PHP und sollte idealerweise in der boot.php des project-AddOns abgelegt werden. Alternativ kann sie an jeder Stelle platziert werden, die während der Initialisierung aufgerufen wird.
Beispiel: YCom-User über die REST-API verwalten
<?php
// diese Zeile ist normalerweise nötig. Dieses Beispiel nutzt aber eine YCom-Tabelle, die bereits über das AddOn registriert ist.
##rex_yform_manager_dataset::setModelClass('rex_ycom_user', rex_ycom_user::class);
// Konfiguration des REST Endpoints.
$route = new \rex_yform_rest_route(
[
'path' => '/v1/users/',
'auth' => '\rex_yform_rest_auth_token::checkToken',
'type' => \rex_ycom_user::class,
'query' => \rex_ycom_user::query(),
'get' => [
'fields' => [
'rex_ycom_user' => [ /* Name der Model-Klasse, nicht der Tabelle, ggf. inkl. Namespace */
'id',
'login',
'email',
'name'
],
'rex_ycom_group' => [ /* Name der Model-Klasse, nicht der Tabelle, ggf. inkl. Namespace */
'id',
'name'
]
]
],
'post' => [
'fields' => [
'rex_ycom_user' => [ /* Name der Model-Klasse, nicht der Tabelle, ggf. inkl. Namespace */
'login',
'email',
'ycom_groups'
]
]
],
'delete' => [
'fields' => [
'rex_ycom_user' => [ /* Name der Model-Klasse, nicht der Tabelle, ggf. inkl. Namespace */
'id',
'login'
]
]
]
]
);
// Einbinden der Konfiguration
\rex_yform_rest::addRoute($route);
Diese Konfiguration ermöglicht das Auslesen und Anlegen von Usern, wobei beim Anlegen nur die Felder login, email und ycom_groups verwendet werden können. Das Löschen ist für alle User möglich. Über Filter bei id oder login können bestimmte User gefiltert und anschließend gelöscht werden.
Route-Konfiguration
path
Erforderlich. Definiert zusammen mit dem Basis-Pfad den Endpoint. Im Beispiel ergibt sich: /rest/v1/users/
auth
Optional. Wenn keine Authentifizierung benötigt wird, kann dieser Parameter weggelassen werden. Erlaubt sind Callbacks und Funktionsnamen.
Die Funktion darf nicht direkt aufgerufen werden, sondern muss als Callback eingetragen werden, damit sie erst bei Bedarf ausgeführt wird.
Beispiele:
'\rex_yform_rest_auth_token::checkToken'- Standardauthentifizierung mit einfachem Token'MeineFunktion'- eigene Funktion
Ohne Authentifizierung kann jeder auf die Daten zugreifen. Dies sollte nur bei öffentlichen Daten wie PLZ-Listen verwendet werden.
table / type / query
Für den Zugriff auf die Tabelle gibt es zwei Möglichkeiten:
Option 1: Mit type und query (empfohlen):
'type' => \rex_ycom_user::class- Die Model-Klasse'query' => \rex_ycom_user::query()- Der Query-Builder für die Abfrage
Option 2: Mit table:
\rex_ycom_user::table()- Definiert direkt die Tabelle, die in YOrm registriert ist
Nutzung eines Endpoints
URL-Format: https://domain/rest/v1/users
Die folgenden Beispiele gehen davon aus, dass keine eigene Authentifizierung konfiguriert ist. Details zum JSON-Format finden sich unter https://jsonapi.org/format/.
GET
Datensätze abrufen
RequestType: GET
URL: https://url.localhost/rest/v1/users/[id]
Header:
Authorization: Bearer [token]
Response:
{
"id": "[id]",
"type": "rex_ycom_user",
"attributes": {
"login": "jannie",
"email": "jan.kristinus@yakamara.de"
},
"relationships": {
"ycom_groups": {
"data": [
{ "type": "tags", "id": "2" },
{ "type": "tags", "id": "3" }
]
}
},
"links": {
"self": "https:\/\/url.localhost\/rest\/v1\/users\/[id]"
}
}
Filter
Das Ergebnis kann über URL-Parameter gefiltert werden. Die internen Suchfilter (getSearchFilter) werden über filter[feldname]=suchwert angesprochen. Ein Suchfeld kann nur verwendet werden, wenn es in der Route als Feld definiert wurde.
Includes
Mit include=title,user.login,user.email lässt sich festlegen, welche Werte zurückgegeben werden sollen. So können kompaktere Ergebnislisten erstellt werden, wenn bestimmte Relationen oder Werte nicht benötigt werden.
Weitere Parameter
| Parameter | Beschreibung |
|---|---|
per_page=x |
Anzahl der Treffer pro Seite |
page=x |
Direkt auf eine bestimmte Ergebnisseite springen |
order[Feldname]=asc oder desc |
Sortierung nach Feldnamen (mehrfach verwendbar) |
POST
Anlegen eines Datensatzes
RequestType: POST
URL: https://url.localhost/rest/v1/users/
Header:
Content-Type: application/json
Authorization: Bearer [token]
Body:
{
"data": {
"type": "rex_ycom_user",
"attributes": {
"login": "jannie",
"email": "jan.kristinus@yakamara.de"
},
"relationships": {
"ycom_groups": {
"data": [
{ "type": "rex_ycom_group", "id": "2" },
{ "type": "rex_ycom_group", "id": "3" }
]
}
}
}
}
Aktualisieren von Datensätzen
Zum Aktualisieren eines bestehenden Datensatzes wird ein POST-Request mit der ID des Datensatzes verwendet:
RequestType: POST
URL: https://url.localhost/rest/v1/users/[id]
Der Body entspricht dem Format beim Anlegen. Es werden nur die im Body enthaltenen Felder aktualisiert.
DELETE
Löschen mit Filtern
RequestType: DELETE
URL: https://url.localhost/rest/v1/users/?filter[login]=jannie
Header:
Authorization: Bearer [token]
Response:
{
"all": 1,
"deleted": 1,
"failed": 0,
"dataset": [{
"id": "[id]"
}]
}
Löschen mit einer ID
RequestType: DELETE
URL: https://url.localhost/rest/v1/users/[id]
oder https://url.localhost/rest/v1/users/?filter[id]=[id]
Header:
Authorization: Bearer [token]
Response:
{
"all": 1,
"deleted": 1,
"failed": 0,
"dataset": [{
"id": "[id]"
}]
}
Response ohne Treffer:
{
"all": 0,
"deleted": 0,
"failed": 0
}
Authentifizierung
Standardauthentifizierung
Bei Verwendung von '\rex_yform_rest_auth_token::checkToken' als Authentifizierungsmethode wird die Token-Verwaltung aus YForm:Rest verwendet.
Die dort erstellten Token werden überprüft und müssen im Header übergeben werden. Nur aktive Token sind funktionsfähig.
Im Backend können Zugriffe eingeschränkt und nachverfolgt werden. Einschränkungen wie maximale Zugriffe pro Stunde sind konfigurierbar. Jeder Zugriff auf die REST-API wird protokolliert.
Header
Eigene Header können global für die REST-API gesetzt werden:
\rex_yform_rest::setHeader('Access-Control-Allow-Origin', '*');
Oder spezifisch für eine Route (überschreibt globale Header):
$route->setHeader('Access-Control-Allow-Origin', 'redaxo.org');
Custom API-Endpoint
// API-Endpoint in lib/Api.php
class Product_Api extends rex_yform_rest
{
public function get()
{
$id = rex_request::get('id', 'int');
if ($id) {
// Einzelner Datensatz
$product = rex_yform_manager_dataset::get($id, 'rex_products');
return $this->sendJson($product ? $product->getData() : null);
}
// Liste
$products = rex_yform_manager_dataset::query('rex_products')
->where('status', 1)
->find();
$data = [];
foreach ($products as $product) {
$data[] = $product->getData();
}
return $this->sendJson($data);
}
public function post()
{
$data = json_decode(file_get_contents('php://input'), true);
$product = rex_yform_manager_dataset::create('rex_products');
$product->setData($data);
if ($product->save()) {
return $this->sendJson($product->getData(), 201);
}
return $this->sendJson(['errors' => $product->getMessages()], 400);
}
}