Skip to content

About

Syncronise Admidio with wordpress

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

WpUserSync (Admidio 5.0 kompatibel)

Dieses Plugin ist eine klassische adm_plugins-Variante für Admidio 5.0.x ohne Abhängigkeit vom neuen Plugin-Manager-Stack.

Enthalten

  • index.php – Infoseite mit Konfigurationsstatus
  • api/api.php – JSON-API für Benutzer, Felder, Rollen, Kategorien, Arbeitsdienste und Mitgliedsart-Wechsel (via .htaccess)
  • classes/Service/MembershipTypeService.php – Mitgliedsart-Wechsel über AdmHistory\MembershipApi
  • classes/Service/WorkHoursService.php – Arbeitsdienst-Stunden über das Plugin Mitgliedsbeitrag (WorkHoursApi)
  • classes/Service/ApiUser.php – setzt den technischen API-Benutzer als angemeldeten Benutzer
  • bootstrap-admidio.php – Bootstrap für klassische Admidio-Strukturen
  • bootstrap-plugin.php – lokaler PSR-4-Autoloader

Installation

  1. Ordner WpUserSync nach adm_plugins/ kopieren.
  2. Konfiguration in adm_my_files/config.php ergänzen (siehe Plugin-Infoseite in Admidio).
  3. Ein langes gemeinsames Secret ($plg_wpusersync_api_secret) setzen.

Konfiguration .htaccess erweitern

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^adm_plugins/wpusersync/api/v1/(.*)$ /adm_plugins/wpusersync/api/api.php [QSA,L]
</IfModule>

Beispiel: Konfiguration in adm_my_files/config.php

$plg_wpusersync_enabled = true;
$plg_wpusersync_require_https = true;
$plg_wpusersync_assign_default_roles = true;
$plg_wpusersync_api_secret = 'mein-langes-zufaelliges-shared-secret';
$plg_wpusersync_nonce_max_age = 300;
// API-Benutzer für alle Änderungen (Pflicht für POST/DELETE, siehe unten)
$plg_wpusersync_api_user_uuid = '00000000-0000-0000-0000-000000000000';
// optional, Standard: adm_plugins/adm-history
// $plg_wpusersync_admhistory_dir = __DIR__ . '/../adm_plugins/adm-history';
// optional, Standard: Ordner MembershipFee bzw. Mitgliedsbeitrag neben WpUserSync
// $plg_wpusersync_membershipfee_dir = __DIR__ . '/../adm_plugins/MembershipFee';

API-Benutzer

Die API hat keine Admidio-Anmeldung. Nach erfolgreicher Signaturprüfung setzt api/api.php deshalb den Benutzer aus $plg_wpusersync_api_user_uuid als angemeldeten Benutzer ($gCurrentUser). Admidio trägt ihn bei allen Änderungen aus WordPress im Änderungsprotokoll ein.

  • Schreibende Anfragen (POST, DELETE) werden ohne gültigen API-Benutzer mit 500 und code: api_user_not_configured bzw. api_user_invalid abgelehnt.
  • Lesende Anfragen (GET) laufen mit dem API-Benutzer, falls konfiguriert, sonst als Gast.
  • Rechte des API-Benutzers prüfen der Mitgliedsart-Wechsel (über adm-history) und der Arbeitsdienst (über das Plugin Mitgliedsbeitrag). Die übrigen Endpunkte schreiben weiterhin ohne Rechteprüfung.

Empfehlung: eigenen Admidio-Benutzer (z. B. „WordPress API“) ohne Login-Daten anlegen und ihm eine Rolle mit dem Recht „Rollen zuordnen“ für die betroffenen Rollen geben.

API-Authentifizierung

GET /adm_plugins/wpusersync/api/v1/core/users/{uuid}
X-Api-Client-Id: <feste_client_id>
X-Api-Timestamp: <unixzeit>
X-Api-Nonce: <zufaelliger_nonce>
X-Api-Body-Sha256: <sha256_hex_des_raw_json>
X-Api-Signature: <hmac_sha256_hex>
Content-Type: application/json

Signatur-Basis (jeweils mit \n getrennt):

METHOD
PATH
CLIENT_ID
TIMESTAMP
NONCE
BODY_SHA256

REST-API Endpunkte (v1)

URLs verwenden das Routing-Pattern via .htaccess:

/adm_plugins/wpusersync/api/v1/...

Alle Endpunkte erfordern HMAC-Request-Signing (siehe Authentifizierung oben).

Profilfeld-Allowlist

Die Allowlist wird auf der Administratorseite /adm_plugins/wpusersync/index.php über getrennte Checkboxen für Lese- und Schreibzugriff gepflegt. Beim Speichern legt das Plugin adm_my_files/wpusersync-profile-fields.json an beziehungsweise aktualisiert diese Datei. Der PHP-Prozess muss Schreibrechte auf adm_my_files haben.

Eine fehlende Allowlist-Datei sperrt Profilfeld-Lese- und Schreibzugriffe standardmäßig (fail-closed). Für POST /core/users/new müssen FIRST_NAME, LAST_NAME und BIRTHDAY in der Schreib-Allowlist aktiviert sein. Benutzerlisten und Suchergebnisse geben diese Profilfelder nur zurück, wenn sie jeweils in der Lese-Allowlist stehen.

Benutzer und Stammdaten

  • GET /core/users – Liste aller Benutzer (mit ?limit=50&offset=0)
  • GET /core/users/{uuid} – Benutzer anhand seiner UUID auslesen
  • GET /core/search?firstName=...&lastName=...&birthday=... – Benutzer anhand Name und Geburtstag suchen
  • POST /core/users/new – Benutzer anlegen (erfordert firstName, lastName und birthday)
  • GET /core/roles – Rollen auflisten
  • GET /core/categories – Kategorien auflisten
  • GET /core/categories/{type} – Kategorien nach Typ auflisten

Benutzerdefinierte Felder

  • GET /core/users/{uuid}/fields – Profilfelder des Benutzers auslesen
  • GET /core/users/{uuid}/fields/{name} – Einzelnes Profilfeld auslesen
  • POST /core/users/{uuid}/fields – Profilfelder setzen (mit {"data":{"FELDNAME":"Wert"}})
  • POST /core/users/{uuid}/fields/{name} – Einzelnes Profilfeld setzen (mit {"data":"Wert"})

Mitgliedschaften und Arbeitsdienste

  • GET /core/users/{uuid}/memberships – Mitgliedschaften des Benutzers auslesen
  • GET /core/users/{uuid}/memberships/{year} – Mitgliedschaften für ein Jahr auslesen
  • POST /core/users/{uuid}/memberships – Rollenmitgliedschaften zuweisen (mit {"roles":{"Rollenname":{"start_date":"YYYY-MM-DD","end_date":"YYYY-MM-DD"}}})
  • POST /core/users/{uuid}/mitgliedschaftbfv – BFV-Mitgliedschaft und Beitragsrollen verwalten
  • Arbeitsdienst: siehe eigener Abschnitt unten.

Arbeitsdienst (über Plugin Mitgliedsbeitrag)

Die Stunden stehen im Plugin Mitgliedsbeitrag (Tabelle adm_plugin_membershipfee_workhours, Seite „Arbeitsdienst erfassen“). WpUserSync ruft dessen Schnittstelle Plugins\MembershipFee\classes\Work\WorkHoursApi auf; alle Regeln stehen dort. Die frühere Tabelle adm_user_arbeitsdienst des alten Plugins „arbeitsdienst“ wird nicht mehr verwendet.

Voraussetzungen:

  • Plugin Mitgliedsbeitrag ab der Version mit classes/Work/WorkHoursApi.php in adm_plugins/MembershipFee (oder Mitgliedsbeitrag, oder $plg_wpusersync_membershipfee_dir). Fehlt es, antworten die Endpunkte mit 501 und code: membershipfee_missing.
  • Zum Schreiben braucht der API-Benutzer die Zugriffsrolle des Beitragsplugins oder muss den Menüpunkt „Arbeitsdienst erfassen“ sehen dürfen (in der Menüverwaltung unter „Sichtbar für“ eintragen). Sonst 403, code: forbidden.

Endpunkte:

  • GET /core/users/{uuid}/arbeitsdienst – alle Jahre mit Einträgen und das aktuelle Jahr
  • GET /core/users/{uuid}/arbeitsdienst/{year} – ein Leistungsjahr
  • POST /core/users/{uuid}/arbeitsdienst – Eintrag anlegen oder (mit id) ändern
  • POST /core/users/{uuid}/arbeitsdienst/{year} – wie oben; das Datum muss im Jahr liegen
  • DELETE /core/users/{uuid}/arbeitsdienst/{id} – Eintrag löschen
  • POST /core/users/{uuid}/arbeitsdienst/soll – Sollstunden setzen (Profilfeld „Sollstunden Arbeitsdienst“), Body {"target_hours": 10}; null leert das Feld. Antwort wie beim Lesen des aktuellen Jahres mit action: "target_updated". Hinweis: „Sollstunden abgleichen“ in Admidio kann den Wert später wieder nach den Regeln setzen.

Anlegen (Datum, Stunden und Einsatz sind Pflicht; name wird wie activity akzeptiert):

{"data": {"date": "2026-04-18", "hours": 2.5, "activity": "Gewässerputzete", "comment": "Ufer Nord"},
 "check_duplicates": true}

Ändern (nur die geänderten Felder): {"data": {"id": 123, "hours": 4}}

Mit check_duplicates (alt: check_dublicates) wird ein Eintrag mit gleichem Datum, Einsatz und Stunden nicht doppelt angelegt; die Antwort hat dann action: "exists" und den vorhandenen Eintrag. Wiederholtes Senden aus WordPress ist damit unschädlich. Die id aus der Antwort sollte WordPress speichern, um später zu ändern oder zu löschen.

Antwort (lesen und schreiben):

{"status": "success", "action": "created",
 "entry": {"id": 123, "date": "2026-04-18", "year": 2026, "hours": 2.5, "activity": "Gewässerputzete", "comment": "Ufer Nord", "created_at": "…", "changed_at": null},
 "user_uuid": "…", "target_hours": 10,
 "years": [{"year": 2026, "done_hours": 2.5, "missing_hours": 7.5, "locked": false, "entries": [ … ]}]}
  • action gibt es nur beim Schreiben: created, updated, exists, deleted.
  • target_hours ist das Profilfeld „Sollstunden Arbeitsdienst“ (ein Wert, nicht je Jahr; null, wenn leer). missing_hours rechnet wie die Jahresübersicht mit diesem Wert.
  • locked: true heißt: Das Jahr ist abgerechnet (Arbeitsdienst exportiert oder eingezogen). Schreiben und Löschen antworten dann mit 409, code: year_locked; Korrekturen nur noch in Admidio.
  • Weitere Fehler: 404 user_not_found, 404 not_found (Eintrag gehört nicht zum Mitglied), 422 not_member_in_year (Mitglied im Leistungsjahr in keiner Rolle), 422 validation_failed.
  • Beträge (Ersatzbeitrag) gibt die API nicht aus.

Mitgliedsart wechseln (über Plugin adm-history)

Voraussetzung: Das Plugin „Mitglieder-Historie“ liegt in adm_plugins/adm-history (oder in $plg_wpusersync_admhistory_dir). Erlaubte Wechsel, Pflicht- und optionale Beitragsrollen stehen ausschließlich in adm-history/mitgliedsarten.php und werden von AdmHistory\MembershipApi geprüft. Ein Wechsel gilt immer ab dem 1. Januar, nur für das aktuelle Jahr und das Folgejahr.

Geändert wird im Namen des API-Benutzers (siehe „API-Benutzer“). Für den Wechsel braucht er das Recht, Mitglieder aller Mitgliedsart-, gemeinsamen und Beitragsrollen zuzuordnen.

  • GET /core/mitgliedsarten – konfigurierte Mitgliedsarten mit Rollen, Pflicht-/optionalen Beitragsrollen und erlaubten Zielen
  • GET /core/users/{uuid}/mitgliedsart – je Jahr (aktuell, Folgejahr): Mitgliedsart am 31.12., Zusatzbeiträge und options (bisherige Art plus erlaubte Ziele mit ihren optionalen Beitragsrollen) – geeignet, um in WordPress die Auswahl aufzubauen
  • POST /core/users/{uuid}/mitgliedsart – Mitgliedsart und Zusatzbeiträge setzen:
    • year (Pflicht): aktuelles Jahr oder Folgejahr
    • art (Pflicht): Kürzel oder Name, z. B. "A" oder "Aktiv"; "" = Kündigung
    • fee (optional): genau diese optionalen Beitragsrollen gelten danach im Jahr, [] entfernt alle. Fehlt fee, bleiben bisherige Zusatzbeiträge, soweit sie zur neuen Mitgliedsart gehören.
{"year": 2027, "art": "A", "fee": ["Bootsbeitrag"]}

Antwort: art, name, fees, operations (Anzahl Datenbankänderungen, 0 = nichts zu tun) und der neue Stand years wie beim GET. Fachliche Fehler (nicht erlaubter Wechsel, unpassender Zusatzbeitrag, fehlende Rechte) antworten mit 422 und code: membership_change_failed.

Schreibzugriffe verwenden JSON im Request-Body. Der Router unterstützt nur die oben aufgeführten HTTP-Methoden und Routen; nicht aufgeführte Routen antworten mit 404.

Beispiel-Requests

Benutzer auslesen:

curl -X GET https://example.org/adm_plugins/wpusersync/api/v1/core/users/00000000-0000-0000-0000-000000000000 \
  -H "X-Api-Client-Id: wordpress-prod" \
  -H "X-Api-Timestamp: $(date +%s)" \
  -H "X-Api-Nonce: $(openssl rand -hex 16)" \
  -H "X-Api-Body-Sha256: $(echo -n '' | sha256sum | cut -d' ' -f1)" \
  -H "X-Api-Signature: <HMAC-SHA256>" \
  -H "Content-Type: application/json"

Custom-Field setzen:

PAYLOAD='{"data":"neuer-wert"}'
curl -X POST https://example.org/adm_plugins/wpusersync/api/v1/core/users/00000000-0000-0000-0000-000000000000/fields/mein_feld \
  -H "X-Api-Client-Id: wordpress-prod" \
  -H "X-Api-Timestamp: $(date +%s)" \
  -H "X-Api-Nonce: $(openssl rand -hex 16)" \
  -H "X-Api-Body-Sha256: $(echo -n "$PAYLOAD" | sha256sum | cut -d' ' -f1)" \
  -H "X-Api-Signature: <HMAC-SHA256>" \
  -H "Content-Type: application/json" \
  -d "$PAYLOAD"

About

Syncronise Admidio with wordpress

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages