This package was developed to give you a quick start to communicate with the DocuWare REST API. It is used to query the most common endpoints.
- Navigation
- 💡 What is DocuWare?
- 🛠 Requirements
- ⚙️ Installation
- 🏗 Usage
- Getting Started with OAuth
- Getting a new token via Username & Password:
- Getting a new token via Username & Password (Trusted User):
- Available Requests
- Organization
- User Management
- File Cabinets
- General
- Dialogs
- Search
- Get A Specific Document From A File Cabinet
- Get Documents From A File Cabinet
- Most basic example to search for documents.
- Search in multiple file cabinets
- Find results on the next page
- Define the number of results which should be shown per page
- Use the full-text search
- Search documents which are created from the first of march.
- Search documents which are created until the first of april.
- Order the results by field name.
- Search documents filtered to the value.
- Search documents filtered to multiple values.
- Search documents with empty or non-empty index fields.
- You can specify the dialog which should be used.
- You can also combine everything.
- Check In Check Out
- Select Lists
- Upload
- Documents
- Workflow
- Extending the connector (EXAMPLE)
- 🖼 Make encrypted URLs
- 🏋️ Document Index Fields DTO showcase
- 📦 Caching requests
- 💥 Exceptions explained
- ✨ Events
- 🔧 Configuration file
- Postman collection parity & Saloon fixtures
- 🚧 Testing
- 📝 Changelog
- ✏️ Contributing
- 🧑💻 Security Vulnerabilities
- 🙏 Credits
- 🎭 License
DocuWare provides cloud document management and workflow automation software that enables you to digitize, secure and work with business documents, then optimize the processes that power the core of your business.
Version Support
| Version | PHP Version | Laravel Version | DocuWare Cloud Access |
|---|---|---|---|
| v12.0 | ^8.2 - ^8.4 | 12.* | ✅ |
| v11.0 (alpha) | ^8.2 | 11.* | ✅ |
| > v4.0 | ^8.2 | 11.* | ✅ |
| > v3.0 | ^8.2 | 10.* | ✅ |
| > v2.0 | ^8.1 | 9.* | ✅ |
| > v1.2 | ^8.1 | 9.* | ✅ |
| < v1.2 | ^8.0 | 8.* | ✅ |
Current Support
| Group | Request | Supported | TODO |
|---|---|---|---|
| Authentication/OAuth | 1. Get Responsible Identity Service | ✅ | |
| Authentication/OAuth | 2. Get Identity Service Configuration | ✅ | |
| Authentication/OAuth | 3.a Request Token w/ Username & Password | ✅ | |
| Authentication/OAuth | 3.b Request Token w/ a DocuWare Token | 🕣 | |
| Authentication/OAuth | 3.c Request Token w/ Username & Password (Trusted User) | 🕣 | |
| Authentication/OAuth | 3.d.1 Obtain Windows Authorization (On Premises Only) | 🕣 | |
| Authentication/OAuth | 3.d.2 Request Token /w a Windows Account (On Premises Only) | 🕣 | |
| General/Organisation | Get Login Token | ✅ | |
| General/Organisation | Get Organization | ✅ | |
| General/Organisation | Get All File Cabinets and Document Trays | ✅ | |
| General/UserManagement | Get Users by ID | ✅ | |
| General/UserManagement | Get Users of a Role | ✅ | |
| General/UserManagement | Get Users of a Group | ✅ | |
| General/UserManagement | Create User | ✅ | |
| General/UserManagement | Update User | ✅ | |
| General/UserManagement | Get Groups | ✅ | |
| General/UserManagement | Get All Groups for a Specific User | ✅ | |
| General/UserManagement | Add User to a Group | ✅ | |
| General/UserManagement | Remove User from a Group | ✅ | |
| General/UserManagement | Get Roles | ✅ | |
| General/UserManagement | Get All Roles for a Specific User | ✅ | |
| General/UserManagement | Add User to a Role | ✅ | |
| General/UserManagement | Remove User from a Role | ✅ | |
| FileCabinets/General | Get File Cabinet Information | ✅ | |
| FileCabinets/General | Get Total Number of Documents | ✅ | |
| FileCabinets/Dialogs | Get All Dialogs | ✅ | |
| FileCabinets/Dialogs | Get a Specific Dialog | ✅ | |
| FileCabinets/Dialogs | Get Dialogs of a Specific Type | ✅ | |
| FileCabinets/Search | Get Documents from a File Cabinet | ✅ | |
| FileCabinets/Search | Get a Specific Document From a File Cabinet | ✅ | |
| FileCabinets/Search | Search for Documents in a Single File Cabinet | ✅ | |
| FileCabinets/Search | Search for Documents in Multiple File Cabinets | ✅ | |
| FileCabinets/CheckInCheckOut | Check-out & Download a Document | ✅ | CheckoutDocumentToFileSystem |
| FileCabinets/CheckInCheckOut | Check-in a Document from the File System | ✅ | CheckInDocumentFromFileSystem |
| FileCabinets/CheckInCheckOut | Undo Check-out | ✅ | UndoDocumentCheckout |
| FileCabinets/SelectLists | Get Select Lists & Get Filtered Select Lists | ✅ | |
| FileCabinets/Upload | Create Data Record | ✅ | |
| FileCabinets/Upload | Append File(s) to a Data Record | ✅ | |
| FileCabinets/Upload | Upload a Single File for a Data Record | ✅ | CreateDataRecord (multipart POST …/Documents) |
| FileCabinets/Upload | Create a Data Record & Upload File | ✅ | CreateDataRecord |
| FileCabinets/Upload | Create Data Record & Upload File Using Store Dialog | ✅ | CreateDataRecord + storeDialogId |
| FileCabinets/Upload | Append a Single PDF to a Document | ✅ | - |
| FileCabinets/Upload | Replace a PDF Document Section | ✅ | |
| FileCabinets/BatchIndexFieldsUpdate | Batch Update Index Fields By Id | ✅ | BatchDocumentsUpdateFields |
| FileCabinets/BatchIndexFieldsUpdate | Batch Update Index Fields By Search | ✅ | BatchDocumentsUpdateFields |
| FileCabinets/BatchIndexFieldsUpdate | Batch Append/Update Keyword Fields By Id | ✅ | BatchDocumentsUpdateFields |
| Documents/UpdateIndexValues | Update Index Values | ✅ | |
| Documents/UpdateIndexValues | Update Table Field Values | ✅ | UpdateIndexValues + IndexTableDTO |
| Documents/ModifyDocuments | Transfer Document | ✅ | |
| Documents/ModifyDocuments | Delete Document | ✅ | |
| Documents/ClipUnclip&StapleUnstaple | Clip | ✅ | |
| Documents/ClipUnclip&StapleUnstaple | Unclip | ✅ | |
| Documents/ClipUnclip&StapleUnstaple | Staple | ✅ | |
| Documents/ClipUnclip&StapleUnstaple | Unstaple | ✅ | |
| Documents/AnnotationsStamps | AddStampWithPosition | ✅ | AddDocumentAnnotations |
| Documents/AnnotationsStamps | AddStampWithBestPosition | ✅ | AddDocumentAnnotations |
| Documents/AnnotationsStamps | AddTextAnnotation | ✅ | AddDocumentAnnotations |
| Documents/AnnotationsStamps | AddRectEntryAnnotation | ✅ | AddDocumentAnnotations |
| Documents/AnnotationsStamps | AddLineEntryAnnotation | ✅ | AddDocumentAnnotations |
| Documents/AnnotationsStamps | AddPolyLineEntryAnnotation | ✅ | AddDocumentAnnotations |
| Documents/AnnotationsStamps | DeleteAnnotation | ❌ | — |
| Documents/AnnotationsStamps | UpdateTextAnnotation | ❌ | — |
| Documents/AnnotationsStamps | Get Stamps | ✅ | GetStamps |
| Documents/DocumentsTrashBin | Get Documents | ✅ | |
| Documents/DocumentsTrashBin | Delete Documents | ✅ | |
| Documents/DocumentsTrashBin | Restore Documents | ✅ | |
| Documents/ApplicationProperties | Get Application Properties | ✅ | |
| Documents/ApplicationProperties | Add Application Properties | ✅ | |
| Documents/ApplicationProperties | Delete Application Properties | ✅ | |
| Documents/ApplicationProperties | Update Application Properties | ✅ | |
| Documents/Sections | Get All Sections from a Document | ✅ | |
| Documents/Sections | Get a Specific Section | ✅ | |
| Documents/Sections | Delete Section | ✅ | |
| Documents/Sections/Textshot | Get Textshot for a Specific Section | ✅ | |
| Documents/Download | Download Document | ✅ | |
| Documents/Download | Download Section | ✅ | |
| Documents/Download | Download Thumbnail | ✅ | |
| Workflow | Get Document Workflow History | ✅ | |
| Workflow | Get Document Workflow History Steps | ✅ |
You can install the package via composer:
composer require codebar-ag/laravel-docuwareAdd the following environment variables to your .env file:
DOCUWARE_URL=https://domain.docuware.cloud
DOCUWARE_USERNAME=user@domain.test
DOCUWARE_PASSWORD=password
DOCUWARE_PASSPHRASE="passphrase"
DOCUWARE_TIMEOUT=30
DOCUWARE_CACHE_DRIVER=file
DOCUWARE_CACHE_LIFETIME_IN_SECONDS=60
DOCUWARE_CLIENT_ID=docuware.platform.net.client
DOCUWARE_SCOPE=docuware.platformWith the passphrase we are able to encrypt the URLs.
# ❌ Passphrase contains a backslash and is not escaped:
DOCUWARE_PASSPHRASE="a#bcd>2~C1'abc\#"
# ✅ We need to escape the backslash with another backslash:
DOCUWARE_PASSPHRASE="a#bcd>2~C1'abc\\#"This package automatically handles the generation of OAuth token for you and stores them in cache.
use CodebarAg\DocuWare\Connectors\DocuWareConnector;
use CodebarAg\DocuWare\DTO\Config\ConfigWithCredentials;
$connector = new DocuWareConnector(
configuration: new ConfigWithCredentials(
username: 'username',
password: 'password',
)
);use CodebarAg\DocuWare\Connectors\DocuWareConnector;
use CodebarAg\DocuWare\DTO\Config\ConfigWithCredentialsTrustedUser;
$connector = new DocuWareConnector(
configuration: new ConfigWithCredentialsTrustedUser(
username: 'username',
password: 'password',
impersonatedUsername: 'impersonatedUsername',
)
);The package provides several enums to ensure type safety and consistency when working with DocuWare API values.
Represents different connection types for DocuWare authentication:
use CodebarAg\DocuWare\Enums\ConnectionEnum;
ConnectionEnum::WITHOUT_COOKIE;
ConnectionEnum::STATIC_COOKIE;
ConnectionEnum::DYNAMIC_COOKIE;Represents different types of dialogs in DocuWare:
use CodebarAg\DocuWare\Enums\DialogType;
DialogType::SEARCH;
DialogType::STORE;
DialogType::RESULT;
DialogType::INDEX;
DialogType::LIST;
DialogType::FOLDERS; Represents different field types used in DocuWare document indexing:
use CodebarAg\DocuWare\Enums\DocuWareFieldTypeEnum;
DocuWareFieldTypeEnum::STRING;
DocuWareFieldTypeEnum::INT;
DocuWareFieldTypeEnum::DECIMAL;
DocuWareFieldTypeEnum::DATE;
DocuWareFieldTypeEnum::DATETIME;
DocuWareFieldTypeEnum::TABLE;The following sections provide examples for each available request type. All functionality is documented inline below with code examples.
| Request | Supported |
|---|---|
| Get Login Token | ✅ |
| Get Organization | ✅ |
| Get All File Cabinets and Document Trays | ✅ |
use CodebarAg\DocuWare\Requests\General\Organization\GetOrganization;
$organizations = $this->connector->send(new GetOrganization())->dto();use CodebarAg\DocuWare\Requests\General\Organization\GetAllFileCabinetsAndDocumentTrays;
$cabinetsAndTrays = $this->connector->send(new GetAllFileCabinetsAndDocumentTrays())->dto();| Request | Supported |
|---|---|
| Get Users | ✅ |
| Get Users by ID | ✅ |
| Get Users of a Role | ✅ |
| Get Users of a Group | ✅ |
use CodebarAg\DocuWare\Requests\General\UserManagement\GetUsers\GetUsers;
$users = $this->connector->send(new GetUsers())->dto();use CodebarAg\DocuWare\Requests\General\UserManagement\GetUsers\GetUserById;
$user = $this->connector->send(new GetUserById($userId))->dto();use CodebarAg\DocuWare\Requests\General\UserManagement\GetUsers\GetUsersOfARole;
$users = $this->connector->send(new GetUsersOfARole($roleId))->dto();use CodebarAg\DocuWare\Requests\General\UserManagement\GetUsers\GetUsersOfAGroup;
$users = $this->connector->send(new GetUsersOfAGroup($groupId))->dto();| Request | Supported |
|---|---|
| Create User | ✅ |
| Update User | ✅ |
use CodebarAg\DocuWare\Requests\General\UserManagement\CreateUpdateUsers\CreateUser;
$user = $connector->send(new CreateUser(new User(
name: $timestamp.' - Test User',
dbName: $timestamp,
email: $timestamp.'-test@example.test',
password: 'TESTPASSWORD',
)))->dto();use CodebarAg\DocuWare\Requests\General\UserManagement\CreateUpdateUsers\UpdateUser;
$user->name .= ' - Updated';
$user->active = false;
$user = $connector->send(new UpdateUser($user))->dto();| Request | Supported |
|---|---|
| Get Groups | ✅ |
| Get All Groups for a Specific User | ✅ |
| Add User to a Group | ✅ |
| Remove User from a Group | ✅ |
use CodebarAg\DocuWare\Requests\General\UserManagement\GetModifyGroups\GetGroups;
$groups = $connector->send(new GetGroups())->dto();use CodebarAg\DocuWare\Requests\General\UserManagement\GetModifyGroups\GetAllGroupsForASpecificUser;
$groups = $connector->send(new GetAllGroupsForASpecificUser($userId))->dto();use CodebarAg\DocuWare\Requests\General\UserManagement\GetModifyGroups\AddUserToAGroup;
$response = $connector->send(new AddUserToAGroup(
userId: $userId,
ids: [$groupId],
))->dto();use CodebarAg\DocuWare\Requests\General\UserManagement\GetModifyGroups\RemoveUserFromAGroup;
$response = $connector->send(new RemoveUserFromAGroup(
userId: $userId,
ids: [$groupId],
))->dto();| Request | Supported |
|---|---|
| Get Roles | ✅ |
| Get All Roles for a Specific User | ✅ |
| Add User to a Role | ✅ |
| Remove User from a Role | ✅ |
use CodebarAg\DocuWare\Requests\General\UserManagement\GetModifyRoles\GetRoles;
$roles = $this->connector->send(new GetRoles())->dto();use CodebarAg\DocuWare\Requests\General\UserManagement\GetModifyRoles\GetAllRolesForASpecificUser;
$roles = $connector->send(new GetAllRolesForASpecificUser($userId))->dto();use CodebarAg\DocuWare\Requests\General\UserManagement\GetModifyRoles\AddUserToARole;
$response = $connector->send(new AddUserToARole(
userId: $userId,
ids: [$roleId],
))->dto();use CodebarAg\DocuWare\Requests\General\UserManagement\GetModifyRoles\RemoveUserFromARole;
$response = $connector->send(new RemoveUserFromARole(
userId: $userId,
ids: [$roleId],
))->dto();| Request | Supported |
|---|---|
| Get File Cabinet Information | ✅ |
| Get Total Number of Documents | ✅ |
use CodebarAg\DocuWare\Requests\FileCabinets\General\GetFileCabinetInformation;
$fileCabinet = $connector->send(new GetFileCabinetInformation($fileCabinetId))->dto();use CodebarAg\DocuWare\Requests\FileCabinets\General\GetTotalNumberOfDocuments;
$count = $connector->send(new GetTotalNumberOfDocuments(
$fileCabinetId,
$dialogId
))->dto();| Request | Supported |
|---|---|
| Get All Dialogs | ✅ |
| Get a Specific Dialog | ✅ |
| Get Dialogs of a Specific Type | ✅ |
use CodebarAg\DocuWare\Requests\FileCabinets\Dialogs\GetAllDialogs;
$dialogs = $connector->send(new GetAllDialogs($fileCabinetId))->dto();use CodebarAg\DocuWare\Requests\FileCabinets\Dialogs\GetASpecificDialog;
$dialog = $connector->send(new GetASpecificDialog($fileCabinetId, $dialogId))->dto();use CodebarAg\DocuWare\Enums\DialogType;
use CodebarAg\DocuWare\Requests\FileCabinets\Dialogs\GetDialogsOfASpecificType;
$dialogs = $connector->send(new GetDialogsOfASpecificType($fileCabinetId, DialogType::SEARCH))->dto();| Description | Implemented |
|---|---|
| Get Documents from a File Cabinet | ✅ |
| Get a Specific Document From a File Cabinet | ✅ |
| Search for Documents in a Single File Cabinet | ✅ |
| Search for Documents in Multiple File Cabinets | ✅ |
use CodebarAg\DocuWare\Requests\FileCabinets\Search\GetASpecificDocumentFromAFileCabinet;
$document = $connector->send(new GetASpecificDocumentFromAFileCabinet(
$fileCabinetId,
$documentId
))->dto();use CodebarAg\DocuWare\Requests\FileCabinets\Search\GetDocumentsFromAFileCabinet;
$documents = $connector->send(new GetDocumentsFromAFileCabinet(
$fileCabinetId
))->dto();You only need to provide a valid file cabinet id.
$fileCabinetId = '87356f8d-e50c-450b-909c-4eaccd318fbf';
$paginatorRequest = DocuWare::searchRequestBuilder()
->fileCabinet($fileCabinetId)
->get();
$paginator = $connector->send($paginatorRequest)->dto();Provide an array of file cabinet ids.
$fileCabinetIds = [
'0ee72de3-4258-4353-8020-6a3ff6dd650f',
'3f9cb4ff-82f2-44dc-b439-dd648269064f',
];
$paginatorRequest = DocuWare::searchRequestBuilder()
->fileCabinets($fileCabinetIds)
->get();
$paginator = $connector->send($paginatorRequest)->dto();Default: 1
$paginatorRequest = DocuWare::searchRequestBuilder()
->fileCabinet($id)
->page(2)
->get();
$paginator = $connector->send($paginatorRequest)->dto();Default: 50
$paginatorRequest = DocuWare::searchRequestBuilder()
->fileCabinet($id)
->perPage(30)
->get();
$paginator = $connector->send($paginatorRequest)->dto();You have to activate full-text search in your file cabinet before you can use this feature.
$paginatorRequest = DocuWare::searchRequestBuilder()
->fileCabinet($id)
->fulltext('My secret document')
->get();
$paginator = $connector->send($paginatorRequest)->dto();$paginatorRequest = DocuWare::searchRequestBuilder()
->fileCabinet($id)
->filterDate('DWSTOREDATETIME', '>=', Carbon::create(2021, 3, 1))
->get();
$paginator = $connector->send($paginatorRequest)->dto();$paginatorRequest = DocuWare::searchRequestBuilder()
->fileCabinet($id)
->filterDate('DWSTOREDATETIME', '<', Carbon::create(2021, 4, 1))
->get();
$paginator = $connector->send($paginatorRequest)->dto();Supported values: 'asc', 'desc'
$paginatorRequest = DocuWare::searchRequestBuilder()
->fileCabinet($id)
->orderBy('DWSTOREDATETIME', 'desc')
->get();
$paginator = $connector->send($paginatorRequest)->dto();You can specify multiple filters.
$paginatorRequest = DocuWare::searchRequestBuilder()
->fileCabinet($id)
->filter('TYPE', 'Order')
->filter('OTHER_FIELD', 'other')
->get();
$paginator = $connector->send($paginatorRequest)->dto();$paginatorRequest = DocuWare::searchRequestBuilder()
->fileCabinet($id)
->filterIn('TYPE', ['Order', 'Invoice'])
->get();
$paginator = $connector->send($paginatorRequest)->dto();Use the database field name for
$name(often uppercase in DocuWare), not the dialog display label. These map to DocuWare dialog expressionsEMPTY()andNOTEMPTY()—they are not passed throughfilter()string quoting.
// Documents where STATUS has no index value (DocuWare EMPTY())
$paginatorRequest = DocuWare::searchRequestBuilder()
->fileCabinet($id)
->filterEmpty('STATUS')
->get();
$paginator = $connector->send($paginatorRequest)->dto();// Documents where STATUS has any value (DocuWare NOTEMPTY())
$paginatorRequest = DocuWare::searchRequestBuilder()
->fileCabinet($id)
->filterNotEmpty('STATUS')
->get();
$paginator = $connector->send($paginatorRequest)->dto();$dialogId = 'bb42c30a-89fc-4b81-9091-d7e326caba62';
$paginatorRequest = DocuWare::searchRequestBuilder()
->fileCabinet($id)
->dialog($dialogId)
->get();
$paginator = $connector->send($paginatorRequest)->dto();$paginatorRequest = DocuWare::searchRequestBuilder()
->fileCabinet($id)
->page(2)
->perPage(30)
->fulltext('My secret document')
->filterDate('DWSTOREDATETIME', '>=', Carbon::create(2021, 3, 1))
->filterDate('DWSTOREDATETIME','<',Carbon::create(2021, 4, 1))
->filter('TYPE', 'Order')
->filter('OTHER_FIELD', 'other')
->orderBy('DWSTOREDATETIME', 'desc')
->dialog($dialogId)
->get();
$paginator = $connector->send($paginatorRequest)->dto();| Request | Supported |
|---|---|
| Check-out & Download a Document | ✅ |
| Check-in a Document from the File System | ✅ |
| Undo Check-out | ✅ |
Implemented as
CheckoutDocumentToFileSystem,CheckInDocumentFromFileSystem, andUndoDocumentCheckout. Your file cabinet must have version management enabled; otherwise DocuWare returns HTTP 405.
| Request | Supported |
|---|---|
| Get Select Lists & Get Filtered Select Lists | ✅ |
use CodebarAg\DocuWare\Requests\FileCabinets\SelectLists\GetSelectLists;
$types = $this->connector->send(new GetSelectLists(
$fileCabinetId,
$dialogId,
$fieldName,
))->dto();| Request | Supported |
|---|---|
| Create Data Record | ✅ |
| Append File(s) to a Data Record | ✅ |
| Upload a Single File for a Data Record | ✅ |
| Create a Data Record & Upload File | ✅ |
| Create Data Record & Upload File Using Store Dialog | ✅ |
| Append a Single PDF to a Document | ✅ |
| Replace a PDF Document Section | ✅ |
Postman splits some uploads into separate recipes; this package maps them to
CreateDataRecord(multipartPOST …/Documents, optionalstoreDialogId),AppendFilesToADataRecord,AppendASinglePDFToADocument, andReplaceAPDFDocumentSection.
use CodebarAg\DocuWare\Requests\FileCabinets\Upload\CreateDataRecord;
use CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexTextDTO;
$document = $connector->send(new CreateDataRecord(
$fileCabinetId,
null,
null,
collect([
IndexTextDTO::make('DOCUMENT_LABEL', '::data-entry::'),
]),
))->dto();use CodebarAg\DocuWare\Requests\FileCabinets\Upload\CreateDataRecord;
use CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexDateDTO;
use CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexDateTimeDTO;
use CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexDecimalDTO;
use CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexNumericDTO;
use CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexTableDTO;
use CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexTextDTO;
$tableRows = collect([
collect([
IndexTextDTO::make('TEXT', 'project_1'),
IndexNumericDTO::make('INT', 1),
IndexDecimalDTO::make('DECIMAL', 1.1),
IndexDateDTO::make('DATE', $now),
IndexDateTimeDTO::make('DATETIME', $now),
]),
collect([
IndexTextDTO::make('TEXT', 'project_2'),
IndexNumericDTO::make('INT', 2),
IndexDecimalDTO::make('DECIMAL', 2.2),
IndexDateDTO::make('DATE', $now),
IndexDateTimeDTO::make('DATETIME', $now),
]),
]);
$document = $connector->send(new CreateDataRecord(
$fileCabinetId,
null,
null,
collect([
IndexTableDTO::make('TABLE_NAME', $tableRows)
]),
))->dto();use CodebarAg\DocuWare\Requests\FileCabinets\Upload\AppendFilesToADataRecord;
use Saloon\Data\MultipartValue;
$response = $connector->send(
new AppendFilesToADataRecord(
fileCabinetId: $fileCabinetId,
dataRecordId: $document->id,
files: collect([
new MultipartValue(
name: 'File[]',
value: file_get_contents(__DIR__.'/../../../../Fixtures/files/test-2.pdf'),
filename: 'test-2.pdf',
),
new MultipartValue(
name: 'File[]',
value: file_get_contents(__DIR__.'/../../../../Fixtures/files/test-3.pdf'),
filename: 'test-3.pdf',
),
])
)
)->dto();use CodebarAg\DocuWare\Requests\FileCabinets\Upload\AppendASinglePDFToADocument;
$response = $this->connector->send(new AppendASinglePDFToADocument(
fileCabinetId: $fileCabinetId,
documentId: $document->id,
fileContent: file_get_contents(__DIR__.'/../../../../Fixtures/files/test-2.pdf'),
fileName: 'test-2.pdf',
))->dto();use CodebarAg\DocuWare\Requests\FileCabinets\Upload\ReplaceAPDFDocumentSection;
$response = $this->connector->send(new ReplaceAPDFDocumentSection(
fileCabinetId: $fileCabinetId,
sectionId: $documentWithSections->sections->first()->id,
fileContent: file_get_contents(__DIR__.'/../../../../Fixtures/files/test-3.pdf'),
fileName: 'test-3.pdf',
))->dto();| Request | Supported |
|---|---|
| Batch Update Index Fields By Id | ✅ |
| Batch Update Index Fields By Search | ✅ |
| Batch Append/Update Keyword Fields By Id | ✅ |
Use
BatchDocumentsUpdateFields(same class covers these Postman variants).
use CodebarAg\DocuWare\Requests\Fields\GetFieldsRequest;
$fields = $connector->send(new GetFieldsRequest($fileCabinetId))->dto();| Request | Supported |
|---|---|
| Update Index Values | ✅ |
| Update Table Index Values | ✅ |
| Update Table Field Values | ✅ |
Table columns use
IndexTableDTOin the sameUpdateIndexValuesrequest as scalar fields (see Update Table Data Record below).
use CodebarAg\DocuWare\Requests\Documents\UpdateIndexValues\UpdateIndexValues;
use CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexDateDTO;
$response = $connector->send(new UpdateIndexValues(
$fileCabinetId,
$documentId,
collect([
IndexTextDTO::make('DOCUMENT_LABEL', '::new-data-entry::'),
])
))->dto();use CodebarAg\DocuWare\Requests\Documents\UpdateIndexValues\UpdateIndexValues;
use CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexDateDTO;
use CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexDateTimeDTO;
use CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexDecimalDTO;
use CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexNumericDTO;
use CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexTableDTO;
use CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexTextDTO;
$tableRows = collect([
collect([
IndexTextDTO::make('TEXT', 'project_1'),
IndexNumericDTO::make('INT', 1),
IndexDecimalDTO::make('DECIMAL', 1.1),
IndexDateDTO::make('DATE', $now),
IndexDateTimeDTO::make('DATETIME', $now),
]),
collect([
IndexTextDTO::make('TEXT', 'project_2'),
IndexNumericDTO::make('INT', 2),
IndexDecimalDTO::make('DECIMAL', 2.2),
IndexDateDTO::make('DATE', $now),
IndexDateTimeDTO::make('DATETIME', $now),
]),
]);
$document = $connector->send(new UpdateIndexValues(
$fileCabinetId,
null,
null,
collect([
IndexTableDTO::make('TABLE_NAME', $tableRows)
]),
))->dto();| Request | Supported |
|---|---|
| Transfer Document | ✅ |
| Delete Document | ✅ |
use CodebarAg\DocuWare\Requests\Documents\ModifyDocuments\TransferDocument;
$response = $connector->send(new TransferDocument(
$fileCabinetId,
$destinationFileCabinetId,
$storeDialogId,
$documentId,
$fields,
))->dto();use CodebarAg\DocuWare\Requests\Documents\ModifyDocuments\DeleteDocument;
$connector->send(new DeleteDocument(
$fileCabinetId
$documentId,
))->dto();| Request | Supported |
|---|---|
| Clip | ✅ |
| Unclip | ✅ |
| Staple | ✅ |
| Unstaple | ✅ |
use CodebarAg\DocuWare\Requests\Documents\ClipUnclipStapleUnstaple\Clip;
$clip = $connector->send(new Clip(
$fileCabinetId,
[
$documentId,
$document2Id,
]
))->dto();use CodebarAg\DocuWare\Requests\Documents\ClipUnclipStapleUnstaple\Unclip;
$unclip = $connector->send(new Unclip(
$fileCabinetId,
$clipId
))->dto();use CodebarAg\DocuWare\Requests\Documents\ClipUnclipStapleUnstaple\Staple;
$staple = $connector->send(new Staple(
$fileCabinetId,
[
$documentId,
$document2Id,
]
))->dto();use CodebarAg\DocuWare\Requests\Documents\ClipUnclipStapleUnstaple\Unstaple;
$unclip = $connector->send(new Unstaple(
$fileCabinetId,
$stapleId
))->dto();DocuWare's Postman collection lists several add operations (stamp with position / best position, text, rectangle, line, polyline). They target the same Platform route: POST /FileCabinets/{id}/Documents/{documentId}/Annotation, differing only by JSON ($type, Annotations, AnnotationsPlacement, etc.). This package exposes that as AddDocumentAnnotations with the same payload array you would send from Postman—there are no separate classes per recipe.
Not implemented: DeleteAnnotation and UpdateTextAnnotation are separate operations in the API (different HTTP method or path); there is no Saloon request class for them yet—contributions welcome.
| Request | Supported | Package class |
|---|---|---|
| Get Stamps | ✅ | GetStamps |
| Get Annotations | ✅ | GetDocumentAnnotations |
| AddStampWithPosition | ✅ | AddDocumentAnnotations |
| AddStampWithBestPosition | ✅ | AddDocumentAnnotations |
| AddTextAnnotation | ✅ | AddDocumentAnnotations |
| AddRectEntryAnnotation | ✅ | AddDocumentAnnotations |
| AddLineEntryAnnotation | ✅ | AddDocumentAnnotations |
| AddPolyLineEntryAnnotation | ✅ | AddDocumentAnnotations |
| DeleteAnnotation | ❌ | — |
| UpdateTextAnnotation | ❌ | — |
use CodebarAg\DocuWare\Requests\Documents\Stamps\GetStamps;
$stamps = $connector->send(new GetStamps(
$fileCabinetId,
))->dto();use CodebarAg\DocuWare\Requests\Documents\Stamps\GetDocumentAnnotations;
$annotations = $connector->send(new GetDocumentAnnotations(
$fileCabinetId,
$documentId,
))->dto(); // Collection<int, array<string, mixed>>use CodebarAg\DocuWare\Requests\Documents\Stamps\AddDocumentAnnotations;
$result = $connector->send(new AddDocumentAnnotations(
$fileCabinetId,
$documentId,
[
// Same JSON structure as the matching Postman request (e.g. StampPlacement, TextEntry, …).
],
))->dto();| Request | Supported |
|---|---|
| Get Documents | ✅ |
| Delete Documents | ✅ |
| Restore Documents | ✅ |
You can use the same methods as in the search usage. The only difference is that you have to use the
trashBinmethod after thesearchRequestBuildermethod.
```php
use CodebarAg\DocuWare\DocuWare;
$paginatorRequest = (new DocuWare())
->searchRequestBuilder()
->trashBin()use CodebarAg\DocuWare\Requests\Documents\DocumentsTrashBin\DeleteDocuments;
$delete = $connector->send(new DeleteDocuments([$documentID, $document2ID]))->dto();use CodebarAg\DocuWare\Requests\Documents\DocumentsTrashBin\RestoreDocuments;
$delete = $connector->send(new RestoreDocuments([$documentID, $document2ID]))->dto();| Request | Supported |
|---|---|
| Get Application Properties | ✅ |
| Add Application Properties | ✅ |
| Delete Application Properties | ✅ |
| Update Application Properties | ✅ |
use CodebarAg\DocuWare\Requests\Documents\ApplicationProperties\AddApplicationProperties;
$addProperties = $connector->send(new AddApplicationProperties(
$fileCabinetId,
$documentId,
[
[
'Name' => 'Key1',
'Value' => 'Key1 Value',
],
[
'Name' => 'Key2',
'Value' => 'Key2 Value',
],
],
))->dto();use CodebarAg\DocuWare\Requests\Documents\ApplicationProperties\UpdateApplicationProperties;
$updateProperties = $connector->send(new UpdateApplicationProperties(
$fileCabinetId,
$documentId,
[
[
'Name' => 'Key1',
'Value' => 'Key1 Value Updated',
],
],
))->dto()->sortBy('Name');use CodebarAg\DocuWare\Requests\Documents\ApplicationProperties\DeleteApplicationProperties;
$deleteProperties = $connector->send(new DeleteApplicationProperties(
$fileCabinetId,
$document->id,
[
'Key1',
],
))->dto();use CodebarAg\DocuWare\Requests\Documents\ApplicationProperties\GetApplicationProperties;
$properties = $connector->send(new GetApplicationProperties(
$fileCabinetId,
$document->id,
))->dto();| Request | Supported |
|---|---|
| Get All Sections from a Document | ✅ |
| Get a Specific Section | ✅ |
| Delete Section | ✅ |
| Get Textshot | ✅ |
use CodebarAg\DocuWare\Requests\Documents\Sections\GetAllSectionsFromADocument;
$sections = $connector->send(new GetAllSectionsFromADocument(
$fileCabinetId,
$documentId
))->dto();use CodebarAg\DocuWare\Requests\Documents\Sections\GetASpecificSection;
$section = $connector->send(new GetASpecificSection(
$fileCabinetId,
$sectionsId
))->dto();use CodebarAg\DocuWare\Requests\Documents\Sections\DeleteSection;
$deleted = $connector->send(new DeleteSection(
$fileCabinetId,
$sectionId
))->dto();use CodebarAg\DocuWare\Requests\Documents\Sections\GetTextshot;
$deleted = $connector->send(new GetTextshot(
$fileCabinetId,
$sectionId
))->dto();| Request | Supported |
|---|---|
| Download Document | ✅ |
| Download Section | ✅ |
| Download Thumbnail | ✅ |
use CodebarAg\DocuWare\Requests\Documents\Download\DownloadDocument;
$contents = $connector->send(new DownloadDocument(
$fileCabinetId,
$documentId
))->dto();use CodebarAg\DocuWare\Requests\Documents\Download\DownloadSection;
$contents = $connector->send(new DownloadSection(
$fileCabinetId,
$sectionId
))->dto();use CodebarAg\DocuWare\Requests\Documents\Download\DownloadThumbnail;
$contents = $connector->send(new DownloadThumbnail(
$fileCabinetId,
$sectionId
))->dto();| Request | Supported |
|---|---|
| Get Document Workflow History | ✅ |
| Get Document Workflow History Steps | ✅ |
use CodebarAg\DocuWare\Requests\Workflow\GetDocumentWorkflowHistory;
$history = $this->connector->send(new GetDocumentWorkflowHistory(
$fileCabinetId,
$documentId
))->dto();use CodebarAg\DocuWare\Requests\Workflow\GetDocumentWorkflowHistorySteps;
$historySteps = $this->connector->send(new GetDocumentWorkflowHistorySteps(
$workflowId,
$historyId,
))->dto();We understand it may be repetitive to pass the configuration every time you create a new connector.
You can extend the connector and set the configuration once.
<?php
namespace App\Connectors;
use CodebarAg\DocuWare\Connectors\DocuWareConnector;
use CodebarAg\DocuWare\DTO\Config\ConfigWithCredentials;
class YourOwnDocuWareConnector extends DocuWareConnector
{
public function __construct() {
$configuration = new ConfigWithCredentials(
username: 'username',
password: 'password',
);
parent::__construct($configuration);
}
}use App\Connectors\YourOwnDocuWareConnector;
use CodebarAg\DocuWare\DTO\Config\ConfigWithCredentials;
$connector = new YourOwnDocuWareConnector();use CodebarAg\DocuWare\Facades\DocuWare;$fileCabinetId = '87356f8d-e50c-450b-909c-4eaccd318fbf';
$documentId = 42;
$url = DocuWare::url()
->fileCabinet($fileCabinetId)
->document($documentId)
->make();$basketId = 'b_87356f8d-e50c-450b-909c-4eaccd318fbf';
$url = DocuWare::url()
->basket($basketId)
->document($documentId)
->make();In the example below the URL is valid for one week, afterward the URL is no longer working.
$url = DocuWare::url()
->fileCabinet($fileCabinetId)
->document($documentId)
->validUntil(now()->addWeek())
->make();CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexTextDTO {
+name: "FIELD_TEXT" // string
+value: "Value" // null|string
}CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexNumericDTO {
+name: "FIELD_NUMERIC" // string
+value: 1 // null|int
}CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexDecimalDTO {
+name: "FIELD_DECIMAL" // string
+value: 1.00 // null|int|float
}CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexDateDTO {
+name: "FIELD_DATE" // string
+value: now(), // null|Carbon
}CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexDateTimeDTO {
+name: "FIELD_DATETIME" // string
+value: now(), // null|Carbon
}CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexKeywordDTO {
+name: "FIELD_KEYWORD" // string
+value: "Value" // null|string
}CodebarAg\DocuWare\DTO\Documents\DocumentIndex\IndexMemoDTO {
+name: "FIELD_MEMO" // string
+value: "Value" // null|string
}CodebarAg\DocuWare\DTO\OrganizationIndex {
+id: "2f071481-095d-4363-abd9-29ef845a8b05" // string
+name: "Fake File Cabinet" // string
+guid: "1334c006-f095-4ae7-892b-fe59282c8bed" // string|null
}CodebarAg\DocuWare\DTO\Organization {
+id: "2f071481-095d-4363-abd9-29ef845a8b05" // string
+name: "Fake File Cabinet" // string
+guid: "1334c006-f095-4ae7-892b-fe59282c8bed" // string|null
+additionalInfo: [] // array
+configurationRights: [] // array
}CodebarAg\DocuWare\DTO\FileCabinet {
+id: "2f071481-095d-4363-abd9-29ef845a8b05" // string
+name: "Fake File Cabinet" // string
+color: "Yellow" // string
+isBasket: true // bool
+assignedCabinet: "889c13cc-c636-4759-a704-1e6500d2d70f" // string
}CodebarAg\DocuWare\DTO\Dialog {
+id: "fae3b667-53e9-48dd-9004-34647a26112e" // string
+type: "ResultList" // string
+label: "Fake Dialog" // string
+isDefault: true // boolean
+fileCabinetId: "1334c006-f095-4ae7-892b-fe59282c8bed" // string
}CodebarAg\DocuWare\DTO\Field {
+name: "FAKE_FIELD" // string
+label: "Fake Field" // string
+type: "Memo" // string
+scope: "User" // stringCodebarAg\DocuWare\DTO\Field {
+name: "FAKE_FIELD" // string
+label: "Fake Field" // string
+type: "Memo" // string
+scope: "User" // stringCodebarAg\DocuWare\DTO\Document {
+id: 659732 // integer
+file_size: 765336 // integer
+total_pages: 100 // integer
+title: "Fake Title" // string
+extension: ".pdf" // string
+content_type: "application/pdf" // string
+file_cabinet_id: "a233b03d-dc63-42dd-b774-25b3ff77548f" // string
+created_at: Illuminate\Support\Carbon // Carbon
+updated_at: Illuminate\Support\Carbon // Carbon
+fields: Illuminate\Support\Collection { // Collection|DocumentField[]
#items: array:2 [
0 => CodebarAg\DocuWare\DTO\DocumentField // DocumentField
1 => CodebarAg\DocuWare\DTO\DocumentField // DocumentField
]
}
}CodebarAg\DocuWare\DTO\Section {#23784▶
+id: "5589-5525"
+contentType: "text/plain"
+haveMorePages: true
+pageCount: 1
+fileSize: 32
+originalFileName: "example.txt"
+contentModified: "/Date(1702395557000)/"
+annotationsPreview: false
+hasTextAnnotations: null
}CodebarAg\DocuWare\DTO\DocumentThumbnail {
+mime: "image/png" // string
+data: "somedata" // string
+base64: "data:image/png;base64,WXpJNWRGcFhVbWhrUjBVOQ==" // string
}CodebarAg\DocuWare\DTO\TableRow {
+fields: Illuminate\Support\Collection { // Collection|DocumentField[]
#items: array:2 [
0 => CodebarAg\DocuWare\DTO\DocumentField // DocumentField
1 => CodebarAg\DocuWare\DTO\DocumentField // DocumentField
]
}CodebarAg\DocuWare\DTO\DocumentPaginator
+total: 39 // integer
+per_page: 10 // integer
+current_page: 9 // integer
+last_page: 15 // integer
+from: 1 // integer
+to: 10 // integer
+documents: Illuminate\Support\Collection { // Collection|Document[]
#items: array:2 [
0 => CodebarAg\DocuWare\DTO\Document // Document
1 => CodebarAg\DocuWare\DTO\Document // Document
]
}
+error: CodebarAg\DocuWare\DTO\ErrorBag { // ErrorBag|null
+code: 422 // int
+message: "'000' is not valid cabinet id" // string
}
}All Get Requests are cachable and will be cached by default. To determine if the response is cached you can use the following method:
$connector = new DocuWareConnector();
$response = $connector->send(new GetDocumentRequest($fileCabinetId, $documentId));
$response->isCached(); // false
// Next time the request is sent
$response = $connector->send(new GetDocumentRequest($fileCabinetId, $documentId));
$response->isCached(); // trueTo invalidate the cache for a specific request you can use the following method:
$connector = new DocuWareConnector();
$request = new GetDocumentRequest($fileCabinetId, $documentId);
$request->invalidateCache();
$response = $connector->send($request);To temporarily disable caching for a specific request you can use the following method:
$connector = new DocuWareConnector();
$request = new GetDocumentRequest($fileCabinetId, $documentId);
$request->disableCaching();
$response = $connector->send($request);CodebarAg\DocuWare\Exceptions\UnableToMakeRequest
This is thrown if you are not authorized to make the request.
CodebarAg\DocuWare\Exceptions\UnableToProcessRequest
This is thrown if you passed wrong attributes. For example a file cabinet ID which does not exist.
CodebarAg\DocuWare\Exceptions\UnableToLogin
This exception can only be thrown during the login if the credentials did not match.
CodebarAg\DocuWare\Exceptions\UnableToLoginNoCookies
This exception can only be thrown during the login if there was no cookies in the response from the api.
CodebarAg\DocuWare\Exceptions\UnableToFindPassphrase
This exception can only be thrown during the url making if the passphrase could not be found.
CodebarAg\DocuWare\Exceptions\UnableToMakeUrl
Something is wrong during the URL making.
CodebarAg\DocuWare\Exceptions\UnableToUpdateFields
No fields were supplied.
CodebarAg\DocuWare\Exceptions\UnableToGetDocumentCount
Something is wrong with the response from getting the document count.
Illuminate\Http\Client\RequestException
All other cases if the response is not successfully.
The Following events will be fired:
use CodebarAg\DocuWare\Events\DocuWareResponseLog;
// Log each response from the DocuWare REST API.
DocuWareResponseLog::class => [
//
],You can publish the config file with:
php artisan vendor:publish --provider="CodebarAg\DocuWare\DocuWareServiceProvider" --tag="docuware-config"This is the contents of the published config file:
<?php
return [
/*
|--------------------------------------------------------------------------
| Cache driver
|--------------------------------------------------------------------------
| You may like to define a different cache driver than the default Laravel cache driver.
| In Laravel 12+, CACHE_STORE is used instead of CACHE_DRIVER.
|
*/
'cache_driver' => env('DOCUWARE_CACHE_DRIVER', env('CACHE_STORE', 'file')),
/*
|--------------------------------------------------------------------------
| Requests timeout
|--------------------------------------------------------------------------
| This variable is optional and only used if you want to set the request timeout manually.
|
*/
'timeout' => env('DOCUWARE_TIMEOUT', 15),
/*
|--------------------------------------------------------------------------
| Platform path
|--------------------------------------------------------------------------
|
| Matches Postman {{Platform}} (default DocuWare/Platform).
|
*/
'platform_path' => env('DOCUWARE_PLATFORM_PATH', 'DocuWare/Platform'),
/*
|--------------------------------------------------------------------------
| DocuWare Credentials
|--------------------------------------------------------------------------
|
| Before you can communicate with the DocuWare REST-API it is necessary
| to enter your credentials. You should specify a url containing the
| scheme and hostname. In addition add your username and password.
|
*/
'credentials' => [
'url' => env('DOCUWARE_URL'),
'username' => env('DOCUWARE_USERNAME'),
'password' => env('DOCUWARE_PASSWORD'),
],
/*
|--------------------------------------------------------------------------
| Passphrase
|--------------------------------------------------------------------------
|
| In order to create encrypted URLs we need a passphrase. This enables a
| secure exchange of DocuWare URLs without anyone being able to modify
| your query strings. You can find it in the organization settings.
|
*/
'passphrase' => env('DOCUWARE_PASSPHRASE'),
/*
|--------------------------------------------------------------------------
| Configurations
|--------------------------------------------------------------------------
|
*/
'configurations' => [
'search' => [
'operation' => 'And',
/*
* Force Refresh
* Determine if result list is retrieved from the cache when ForceRefresh is set
* to false (default) or always a new one is executed when ForceRefresh is set to true.
*/
'force_refresh' => true,
'include_suggestions' => false,
'additional_result_fields' => [],
],
'cache' => [
'driver' => env('DOCUWARE_CACHE_DRIVER', env('CACHE_STORE', 'file')),
'lifetime_in_seconds' => env('DOCUWARE_CACHE_LIFETIME_IN_SECONDS', 60),
],
'request' => [
'timeout_in_seconds' => env('DOCUWARE_TIMEOUT', 60),
],
'client_id' => env('DOCUWARE_CLIENT_ID', 'docuware.platform.net.client'),
'scope' => env('DOCUWARE_SCOPE', 'docuware.platform'),
],
/*
|--------------------------------------------------------------------------
| Tests
|--------------------------------------------------------------------------
|
*/
'tests' => [
'file_cabinet_id' => env('DOCUWARE_TESTS_FILE_CABINET_ID'),
'dialog_id' => env('DOCUWARE_TESTS_DIALOG_ID'),
'basket_id' => env('DOCUWARE_TESTS_BASKET_ID'),
'org_id' => env('DOCUWARE_TESTS_ORG_ID', env('DOCUWARE_TESTS_ORGANIZATION_ID')),
'search_dialog_id' => env('DOCUWARE_TESTS_SEARCH_DIALOG_ID'),
'store_dialog_id' => env('DOCUWARE_TESTS_STORE_DIALOG_ID'),
'document_id' => env('DOCUWARE_TESTS_DOCUMENT_ID'),
],
];The official DocuWare Postman collection uses {{ServerUrl}} and {{Platform}} (default DocuWare/Platform). This package maps them to Laravel env vars — see .env.example for a Postman variable → DOCUWARE_* table.
- Parity matrix (endpoints vs request classes):
docs/postman-parity.md. - Platform path:
DOCUWARE_PLATFORM_PATH(used byDocuWareConnector,GetResponsibleIdentityService, and encrypted Web Client URLs inDocuWareUrl). - CI-friendly tests: Default
composer testruns unit, DTO, and Saloon fixture tests (tests/Feature/SaloonFixtures). HTTP responses are replayed from JSON files undertests/Fixtures/saloon/using Saloon fixtures (MockClient+Fixture). Bodies use Saloon’s recorded format:statusCode,headers,data(raw response body),context. - Recording fixtures (optional): Edit
tests/Manual/RecordGetOrganizationFixtureTest.php, remove the->skip(...), set realDOCUWARE_*credentials, then run:(composer test:manual
composer test:manualruns onlytests/Manual.) The recorder only writestests/Fixtures/saloon/get-organization.jsonwhen the HTTP response is successful and looks like JSON, so a bad run (HTML error page, 401, etc.) does not overwrite a good committed fixture—the test fails instead. Review the generated JSON for secrets, commit if safe, then restore the skip. - Live tenant tests (destructive cleanup, real API):
composer test:liveruns theintegrationPHPUnit testsuite (tests/Integration). Requires valid DocuWare credentials and test cabinet IDs inphpunit.xmlor the environment. Do not run integration against DocuWare withpest --parallelor multiple concurrenttest:liveprocesses (rate limits and shared cabinet cleanup). Use a single sequential run.
Copy your own phpunit.xml-file.
cp phpunit.xml.dist phpunit.xmlModify environment variables in the phpunit.xml-file:
<env name="DOCUWARE_URL" value="https://domain.docuware.cloud"/>
<env name="DOCUWARE_PLATFORM_PATH" value="DocuWare/Platform"/>
<env name="DOCUWARE_USERNAME" value="user@domain.test"/>
<env name="DOCUWARE_PASSWORD" value="password"/>
<env name="DOCUWARE_PASSPHRASE" value="passphrase"/>
<env name="DOCUWARE_TIMEOUT" value="30"/>
<env name="DOCUWARE_CACHE_DRIVER" value="file"/>
<env name="DOCUWARE_CACHE_LIFETIME_IN_SECONDS" value="0"/>
<env name="DOCUWARE_CLIENT_ID" value="docuware.platform.net.client"/>
<env name="DOCUWARE_SCOPE" value="docuware.platform"/>
<env name="DOCUWARE_TESTS_FILE_CABINET_ID" value=""/>
<env name="DOCUWARE_TESTS_DIALOG_ID" value=""/>
<env name="DOCUWARE_TESTS_BASKET_ID" value=""/>
<env name="DOCUWARE_TESTS_ORG_ID" value=""/>
<env name="DOCUWARE_TESTS_SEARCH_DIALOG_ID" value=""/>
<env name="DOCUWARE_TESTS_STORE_DIALOG_ID" value=""/>
<env name="DOCUWARE_TESTS_DOCUMENT_ID" value=""/>Default test run (no live DocuWare required):
composer testAgainst a real system (integration suite):
composer test:liveRun integration one process at a time (no pest --parallel). Keep real credentials in a local phpunit.xml (this file is gitignored in this repo); use GitHub Actions secrets in CI.
In GitHub Actions (.github/workflows/run-tests.yml), every matrix job runs composer test first; composer test:live runs only on PHP 8.3 with prefer-stable, and only when DOCUWARE_URL, DOCUWARE_USERNAME, and DOCUWARE_PASSWORD are set as repository secrets (optional DOCUWARE_PASSPHRASE and DOCUWARE_TESTS_* IDs as needed).
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
- Sebastian Bürgin-Fix
- All Contributors
- Skeleton Repository from Spatie
- Laravel Package Training from Spatie
The MIT License (MIT). Please see License File for more information.
