https://github.com/pitwch/php-wrapper-proffix-restapi
PHP Wrapper für die PROFFIX REST API
https://github.com/pitwch/php-wrapper-proffix-restapi
proffix rest rest-api rest-client restful-api wrapper-api
Last synced: 4 months ago
JSON representation
PHP Wrapper für die PROFFIX REST API
- Host: GitHub
- URL: https://github.com/pitwch/php-wrapper-proffix-restapi
- Owner: pitwch
- License: mit
- Created: 2018-04-19T12:16:42.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2025-11-11T14:49:05.000Z (7 months ago)
- Last Synced: 2025-11-11T16:24:17.628Z (7 months ago)
- Topics: proffix, rest, rest-api, rest-client, restful-api, wrapper-api
- Language: PHP
- Size: 910 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG_SESSION_CACHING.md
- License: LICENSE
Awesome Lists containing this project
README
# PHP Wrapper für PROFFIX REST-API
Ein effizienter PHP Wrapper für die PROFFIX REST-API.

## Installation
Der Wrapper kann via [Composer](https://getcomposer.org) installiert werden.
```php
composer require pitwch/rest-api-wrapper-proffix-php
```
## Konfiguration
### Initialisierung
Autoload der `RestAPIWrapperProffix` Klasse:
```php
require __DIR__ . '/vendor/autoload.php';
use Pitwch\RestAPIWrapperProffix\Client;
```
Die Konfiguration wird dem Client mitgegeben:
| Konfiguration | Beispiel | Bemerkung |
|------------------|----------------------------------------------------------------------------------|--------------------------------------------------|
| url | `https://myserver.ch:999` | URL der REST-API **ohne pxapi/v2/** |
| apiDatabase | `DEMO` | Name der Datenbank |
| apiUser | `USR` | Name des Benutzers |
| apiPassword | `b62cce2fe18f7a156a9c...` | SHA256-Hash des Benutzerpasswortes |
| apiModule | `ADR,STU` | Benötigte Module (mit Komma getrennt) |
| options | `array('key'=>'112a5a90...')` | Optionen (Details unter Optionen) |
### Beispiel für die Initialisierung
```php
require __DIR__ . '/vendor/autoload.php';
use Pitwch\RestAPIWrapperProffix\Client;
$pxrest = new Client(
'https://myserver.ch:999',
'DEMO',
'USR',
'b62cce2fe18f7a156a9c719c57bebf0478a3d50f0d7bd18d9e8a40be2e663017',
'ADR,STU',
['key'=>'112a5a90fe28b23ed2c776562a7d1043957b5b79fad242b10141254b4de59028','limit'=>2]
);
$adressen = $pxrest->get('ADR/Adresse', ['filter'=>'GeaendertAm>d\'2018-05-17 14:54:56\'', 'depth'=>1, 'fields'=>'AdressNr,Name,GeaendertAm']);
print_r($adressen);
```
## Optionen
Optionen sind **fakultativ** und werden in der Regel nicht benötigt:
| Option | Beispiel | Bemerkung |
|-------------------------|----------------------------------------|----------------------------------------------------------------|
| key | `112a5a90fe28b...` | API-Key als SHA256 - Hash (kann auch direkt mitgegeben werden) |
| version | `v2` | API-Version; Standard = v2 |
| api_prefix | `/pxapi/` | Prefix für die API; Standard = /pxapi/ |
| login_endpoint | `PRO/Login` | Endpunkt für Login; Standard = PRO/Login |
| user_agent | `php-wrapper-proffix-restapi` | User Agent; Standard = php-wrapper-proffix-restapi |
| timeout | `15` | Timeout für Curl in Sekunden; Standard = 15 |
| follow_redirects | `true` | Weiterleitungen der API folgen; Standard = false |
| enable_session_caching | `true` | Session-Caching aktivieren; Standard = true |
| cache_dir | `/tmp/proffix-cache` | Eigenes Cache-Verzeichnis; Standard = plattformspezifisch |
### Session-Caching
Der Wrapper unterstützt automatisches Session-Caching, um die Performance zu verbessern und die Anzahl der Login-Requests zu reduzieren. Das Session-Caching ist standardmässig **aktiviert**.
**Funktionsweise:**
- Nach einem erfolgreichen Login wird die `PxSessionId` in einer Datei gespeichert
- Bei nachfolgenden Requests wird zuerst versucht, die gespeicherte Session zu laden
- Bei ungültigen Sessions (401-Fehler) wird automatisch ein neuer Login durchgeführt
- Sessions werden automatisch beim Logout oder bei Fehlern gelöscht
**Cache-Speicherort:**
Der Cache-Speicherort kann über die Option `cache_dir` angepasst werden. Dies ist besonders nützlich bei Hosting-Umgebungen mit `open_basedir`-Einschränkungen.
**Standard-Speicherorte** (wenn `cache_dir` nicht angegeben):
- **Windows:** `%APPDATA%/php-wrapper-proffix-restapi/`
- **Linux/Mac:** `~/.cache/php-wrapper-proffix-restapi/` oder `/tmp/php-wrapper-proffix-restapi/`
Der Dateiname wird aus Benutzername, Datenbank und URL generiert, um Konflikte bei mehreren Clients zu vermeiden.
**Eigenes Cache-Verzeichnis verwenden:**
```php
$pxrest = new Client(
'https://myserver.ch:999',
'DEMO',
'USR',
'b62cce2fe18f7a156a9c719c57bebf0478a3d50f0d7bd18d9e8a40be2e663017',
'ADR,STU',
[
'enable_session_caching' => true,
'cache_dir' => '/tmp/proffix-cache' // Eigenes Verzeichnis
]
);
```
**Empfohlene Cache-Verzeichnisse für verschiedene Umgebungen:**
```php
// Shared Hosting (z.B. Plesk) mit open_basedir-Einschränkungen
'cache_dir' => '/tmp/proffix-cache'
// Cross-Platform (empfohlen)
'cache_dir' => sys_get_temp_dir() . '/proffix-cache'
// Innerhalb des Projekts
'cache_dir' => __DIR__ . '/cache'
```
**Technische Details:**
Die Session-Verwaltung erfolgt über die `SessionCache`-Klasse (`src/RestAPIWrapperProffix/HttpClient/SessionCache.php`), die folgende Funktionen bietet:
- `load()`: Lädt eine gespeicherte Session-ID aus dem Cache
- `save($sessionId)`: Speichert eine Session-ID im Cache
- `clear()`: Löscht die gespeicherte Session-ID
- Unterstützung für eigene Cache-Verzeichnisse (Option `cache_dir`)
- Automatische Erkennung des plattformspezifischen Cache-Verzeichnisses
- Thread-sichere Dateioperationen mit `LOCK_EX`
- Kollisionsvermeidung durch Base64-URL-kodierte Dateinamen
**Cache-Verzeichnis-Priorität:**
1. Eigenes Verzeichnis (wenn `cache_dir` Option gesetzt)
2. Plattformspezifische Standard-Verzeichnisse
3. Fallback auf `/tmp/` oder `sys_get_temp_dir()`
**Session-Caching deaktivieren:**
```php
$pxrest = new Client(
'https://myserver.ch:999',
'DEMO',
'USR',
'b62cce2fe18f7a156a9c719c57bebf0478a3d50f0d7bd18d9e8a40be2e663017',
'ADR,STU',
['enable_session_caching' => false]
);
```
## Methoden
### Allgemeine Methoden (`get`, `put`, `post`, `delete`)
| Parameter | Typ | Bemerkung |
|------------|--------|----------------------------------------------------------------------------------------------------------|
| endpoint | `string` | Endpunkt der PROFFIX REST-API; z.B. `ADR/Adresse`, `STU/Rapporte`... |
| data | `array` | Daten (werden automatisch in JSON konvertiert); z.B: `["Name"=>"Demo AG",...]` |
| parameters | `array` | Parameter gemäss [PROFFIX REST API Docs](http://www.proffix.net/Portals/0/content/REST%20API/index.html) |
*Sonderzeichen in den Parametern müssen gegebenfalls mit Escape-Zeichen verwendet werden, z.B:*
```php
// Escape ' with \'
$params = ['filter' => 'GeaendertAm>d\'2018-05-17 14:54:56\'', 'depth' => 1, 'fields' => 'AdressNr,Name,GeaendertAm'];
$pxrest->get('ADR/Adresse', $params);
```
#### Get / Query
```php
// Einfache Abfrage
$adresse = $pxrest->get("ADR/Adresse/1");
echo $adresse->Name; // DEMO AG
// Abfrage mit Parametern
$params = ['filter'=>'GeaendertAm>d\'2018-05-17 14:54:56\'','depth'=>1,'fields'=>'AdressNr,Name,GeaendertAm','limit'=>5];
$adressen = $pxrest->get("ADR/Adresse", $params);
```
#### Put / Update
```php
$data = ["AdressNr"=>1, "Ort"=>"Zürich", "PLZ"=>8000, "EMail"=>"test@test.com"];
$adresse = $pxrest->put("ADR/Adresse", $data);
```
#### Post / Create
```php
$data = ["Ort"=>"Zürich", "PLZ"=>8000, "EMail"=>"test@test.com"];
$neueAdresse = $pxrest->post("ADR/Adresse", $data);
```
#### Delete
```php
$response = $pxrest->delete("ADR/Adresse/42");
```
### Spezifische Methoden
#### `getList(int $listenr, array $body = [])`
Generiert eine PROFFIX-Liste (z.B. ein PDF) und gibt das Ergebnis als `Response`-Objekt zurück, welches den rohen Dateiinhalt enthält.
| Parameter | Typ | Bemerkung |
|-----------|----------|------------------------------------------------------------------------------------------------------------------------------------------------|
| `$listenr`| `int` | Die `ListeNr` der Liste, die generiert werden soll. |
| `$body` | `array` | (Optional) Ein assoziatives Array mit Parametern für die Listengenerierung. **Wichtig:** Es muss mindestens ein leeres JSON-Objekt (`{}`) gesendet werden. |
*Beispiel:*
```php
$listeNr = 1029; // Beispiel-ID für ADR_Adressliste.repx
$pdfResponse = $pxrest->getList($listeNr);
if ($pdfResponse->getCode() === 200) {
file_put_contents('Adressliste.pdf', $pdfResponse->getBody());
echo "Liste erfolgreich als Adressliste.pdf gespeichert.";
}
```
## Spezielle Endpunkte
### Info
Ruft Infos vom Endpunkt `PRO/Info` ab.
*Hinweis: Dieser Endpunkt / Abfrage blockiert keine Lizenz.*
```php
// Variante 1: API-Key direkt mitgeben
$info1 = $pxrest->info('112a5a90fe28b23ed2c776562a7d1043957b5b79fad242b10141254b4de59028');
// Variante 2: API-Key aus Options verwenden (sofern dort hinterlegt)
$info2 = $pxrest->info();
```
### Datenbank
Ruft Infos vom Endpunkt `PRO/Datenbank` ab.
```php
$dbInfo = $pxrest->database();
```
## Response / Antwort
Alle Methoden geben die Response als Array bzw. `NULL` (z.B. bei `DELETE`) zurück. Bei Fehlern wird eine `HttpClientException` mit der Rückmeldung der PROFFIX REST-API geworfen.
### Error Handling
Der Wrapper bietet erweitertes Error Handling, das sowohl allgemeine Fehlermeldungen als auch feldspezifische Validierungsfehler erfasst.
#### Beispiel einer PROFFIX API Fehlerantwort
```json
{
"Fields": [
{
"Reason": "EMPTY",
"Name": "PLZ",
"Message": "PLZ darf nicht leer bleiben!"
},
{
"Reason": "EMPTY",
"Name": "Land",
"Message": "Land darf nicht leer bleiben!"
}
],
"Message": "Mindestens ein Feld ist ungültig."
}
```
#### Fehlerbehandlung mit HttpClientException
```php
use Pitwch\RestAPIWrapperProffix\HttpClient\HttpClientException;
try {
$data = ["Ort" => "Zürich", "PLZ" => "", "Land" => ""];
$neueAdresse = $pxrest->post("ADR/Adresse", $data);
} catch (HttpClientException $e) {
// Hauptfehlermeldung
echo "Fehler: " . $e->getMessage() . "\n";
// "Mindestens ein Feld ist ungültig."
// Prüfen, ob feldspezifische Fehler vorhanden sind
if ($e->hasFieldErrors()) {
echo "Feldvalidierungsfehler:\n";
foreach ($e->getFieldErrors() as $error) {
echo sprintf(
" - %s: %s (Grund: %s)\n",
$error['Name'],
$error['Message'],
$error['Reason']
);
}
// Oder alle Details als formatierte Nachricht
echo "\n" . $e->getDetailedMessage();
}
}
```
**Verfügbare Methoden:**
- `getMessage()`: Gibt die Hauptfehlermeldung zurück
- `hasFieldErrors()`: Prüft, ob feldspezifische Fehler vorhanden sind
- `getFieldErrors()`: Gibt ein Array mit allen Feldfehlern zurück
- `getDetailedMessage()`: Gibt eine formatierte Nachricht mit allen Fehlerdetails zurück
- `getCode()`: Gibt den HTTP-Statuscode zurück
- `getRequest()`: Gibt das Request-Objekt zurück
- `getResponse()`: Gibt das Response-Objekt zurück
Weitere Details und Beispiele finden sich in der [Error Handling Dokumentation](docs/ERROR_HANDLING.md).
### Zusatzinformationen zur Response
Zudem lassen sich Zusatzinformationen zur letzten Response wie folgt ausgeben:
### Letzter Request
```php
$lastRequest = $pxrest->http->getRequest();
$lastRequest->getUrl(); // Get requested URL (string).
$lastRequest->getMethod(); // Get request method (string).
$lastRequest->getParameters(); // Get request parameters (array).
$lastRequest->getHeaders(); // Get request headers (array).
$lastRequest->getBody(); // Get request body (JSON).
```
### Letzte Response
```php
$lastResponse = $pxrest->http->getResponse();
$lastResponse->getCode(); // Response code (int).
$lastResponse->getHeaders(); // Response headers (array).
$lastResponse->getBody(); // Response body (JSON).
```
## Ausnahmen / Spezialfälle
* Endpunkte, welche Leerschläge enthalten (z.B. `LAG/Artikel/PC 7/Bestand`), müssen mit `rawurlencode()` genutzt werden.
## Weitere Beispiele
Im Ordner [/examples](https://github.com/pitwch/php-wrapper-proffix-restapi/tree/master/examples) finden sich weitere auskommentierte Beispiele.
## Weitere Wrapper für die Proffix Rest-API
* [Golang Wrapper für die Proffix Rest-API](https://github.com/pitwch/go-wrapper-proffix-restapi)
* [Dart Wrapper für die Proffix Rest-API](https://github.com/pitwch/dart_proffix_rest)