nodus-it / lexware-office-api
PHP API Client for lexware office
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/nodus-it/lexware-office-api
Requires
- php: ^8.1
- saloonphp/pagination-plugin: ^2.2.0
- saloonphp/rate-limit-plugin: ^2.0.0
- saloonphp/saloon: ^3.0
- spatie/laravel-data: ^4.15.1
Requires (Dev)
- fakerphp/faker: ^1.24
- larastan/larastan: ^2.0
- laravel/pint: ^1.0
- orchestra/testbench: ^8.0
- pestphp/pest: ^2.0
This package is auto-updated.
Last update: 2025-11-06 15:35:24 UTC
README
A comprehensive PHP package for interacting with the Lexware Office API, built on top of the powerful Saloon HTTP client. This package provides a clean, object-oriented interface for managing articles, contacts, invoices, and other entities in Lexware Office.
Features
- π Modern Architecture: Built with PHP 8.1+ features and best practices
- π§ Extensible Design: Easy to add new API endpoints and entities
- π Comprehensive Data Handling: Type-safe data objects with validation
- π Automatic Pagination: Built-in support for paginated API responses
- β‘ Rate Limiting: Automatic rate limiting to comply with API limits
- π§ͺ Testing Support: Comprehensive testing utilities and mock responses
- π Rich Documentation: Extensive PHPDoc and inline documentation
- π‘οΈ Error Handling: Centralized exception handling with detailed error information
Installation
You can install the package via composer:
composer require nodus-it/lexware-office-api
You can publish the config file with:
php artisan vendor:publish --tag="lexware-office"
Set your API token in your .env file (available at https://app.lexoffice.de/addons/public-api):
LEXWARE_OFFICE_API_TOKEN=your-token-here
Configuration
The package provides the following configuration options:
# Authentication LEXWARE_OFFICE_API_TOKEN=your-token-here # API timeouts LEXWARE_OFFICE_CONNECT_TIMEOUT=30 LEXWARE_OFFICE_REQUEST_TIMEOUT=30 # Rate limiting # Cache store used by the rate limiter (Laravel cache store name) LEXWARE_OFFICE_RATE_LIMIT_STORE=file
Usage
Basic Usage
use Nodus\LexwareOfficeApi\Utils\LexwareOfficeConnector; use Nodus\LexwareOfficeApi\Resources\ArticleResource; // Create connector $connector = new LexwareOfficeConnector(); // Create resource $articles = new ArticleResource($connector); // Get all articles $allArticles = $articles->all(); // Get specific article $article = $articles->get('article-id'); // Create new article $newArticle = $articles->create(ArticleData::from([ 'title' => 'New Product', 'articleNumber' => 'PROD-001', 'description' => 'Product description', 'unitName' => 'StΓΌck', 'price' => [ 'currency' => 'EUR', 'netAmount' => 19.99, 'grossAmount' => 23.79, 'taxRatePercentage' => 19.0, ], ]));
Using the Resource Factory
use Nodus\LexwareOfficeApi\Utils\ResourceFactory; use Nodus\LexwareOfficeApi\Utils\LexwareOfficeConnector; $connector = new LexwareOfficeConnector(); // Create resources using factory $articles = ResourceFactory::create('articles', $connector); $contacts = ResourceFactory::create('contacts', $connector); $invoices = ResourceFactory::create('invoices', $connector);
Advanced Filtering
use Nodus\LexwareOfficeApi\Data\Enums\ArticleType; // Filter articles by type $serviceArticles = $articles->findByType(ArticleType::SERVICE); // Filter by article number $specificArticles = $articles->findByArticleNumber('PROD-001'); // Filter by GTIN $gtinArticles = $articles->findByGtin('1234567890123'); // Complex filtering $filteredArticles = $articles->all( filterType: ArticleType::PRODUCT, filterArticleNumber: 'PROD-*' );
Error Handling
use Nodus\LexwareOfficeApi\Exceptions\LexwareOfficeException; try { $article = $articles->get('non-existent-id'); } catch (LexwareOfficeException $e) { if ($e->isValidationError()) { $errors = $e->getValidationErrors(); // Handle validation errors } elseif ($e->isClientError()) { // Handle client errors (4xx) } elseif ($e->isServerError()) { // Handle server errors (5xx) } echo "Error: " . $e->getMessage(); echo "Status: " . $e->getStatusCode(); }
Pagination
// Iterate through all pages foreach ($articles->all() as $article) { echo $article->title . "\n"; } // Manual pagination $paginator = $articles->all(); $firstPage = $paginator->items(); // Get items from first page if ($paginator->hasNextPage()) { $nextPage = $paginator->nextPage(); }
Testing
The package includes comprehensive testing utilities:
use Nodus\LexwareOfficeApi\Tests\LexwareOfficeTestCase; class ArticleTest extends LexwareOfficeTestCase { public function test_can_get_article() { // Mock successful response $this->mockClient->addResponse( $this->mockSuccessResponse($this->getSampleArticleData()) ); $articles = new ArticleResource($this->connector); $article = $articles->get('article-123'); $this->assertEquals('Sample Article', $article->title); $this->assertRequestSent('GET', 'articles/article-123'); } public function test_handles_validation_errors() { $this->mockClient->addResponse( $this->mockValidationErrorResponse([ 'title' => ['Title is required'] ]) ); $this->expectException(LexwareOfficeException::class); $articles = new ArticleResource($this->connector); $articles->create(ArticleData::from([])); } }
Architecture
Base Classes
- BaseResource: Template pattern for all API resources
- BaseRequest: Abstract base for all API requests with common functionality
- BaseData: Enhanced data objects with validation and transformation
- LexwareOfficeException: Centralized error handling
Request Types
- BaseGetRequest: For retrieving single entities
- BaseListRequest: For retrieving collections with pagination
- BaseCreateRequest: For creating new entities
- BaseUpdateRequest: For updating existing entities
- BaseDeleteRequest: For deleting entities
Data Traits
- HasTimestamps: Adds created/updated timestamp handling
- HasVersioning: Adds version control for optimistic locking
Extending the Package
Adding New Resources
- Create a new resource class extending
BaseResource:
class ContactResource extends BaseResource { protected function getEndpoint(): string { return 'contacts'; } protected function getRequestNamespace(): string { return 'Nodus\\LexwareOfficeApi\\Requests\\Contacts'; } protected function getDataClass(): string { return ContactData::class; } }
- Register the resource in the factory:
ResourceFactory::register('contacts', ContactResource::class);
Creating Request Classes
class GetContactRequest extends BaseGetRequest { protected function resolveEndpoint(): string { return "contacts/{$this->id}"; } }
Creating Data Classes
class ContactData extends BaseData { use HasTimestamps; use HasVersioning; public string $id; public ?string $organizationName; public ?PersonData $person; public ?AddressData $addresses; }
API Coverage
Currently implemented:
- β Articles (complete)
Planned:
- π Contacts
- π Invoices
- π Vouchers
- π Quotations
- π Credit Notes
- π Order Confirmations
- π Delivery Notes
- π Recurring Templates
- π Payment Conditions
- π Countries
- π Files
- π Profile
- π Event Subscriptions
Development & Testing
This package uses GitHub Actions for continuous integration and testing:
Automated Testing
- Multi-PHP Version Testing: Tests run on PHP 8.1, 8.2, and 8.3
- Dependency Matrix: Tests with both
prefer-lowestandprefer-stabledependencies - Code Coverage: Comprehensive coverage reporting with Codecov integration
- Code Quality: Automated checks with PHPCS, PHPStan, and PHPMD
- Security Audits: Regular dependency vulnerability scanning
Running Tests Locally
# Install dependencies composer install # Run tests vendor/bin/phpunit # Run tests with coverage vendor/bin/phpunit --coverage-html coverage # Run code quality checks (if tools are installed) vendor/bin/phpcs --standard=PSR12 src/ tests/ vendor/bin/phpstan analyse src/ --level=5 vendor/bin/phpmd src/ text cleancode,codesize,controversial,design,naming,unusedcode
Continuous Integration
The project includes several GitHub Actions workflows:
- Tests: Runs on every push and pull request
- Coverage: Generates and uploads coverage reports
- Security: Weekly dependency security audits
- Release: Automated releases for tagged versions
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Development Guidelines
- Follow PSR-12 coding standards
- Write comprehensive tests for new features
- Update documentation for API changes
- Ensure all CI checks pass before submitting PR
License
The MIT License (MIT). Please see License File for more information.