Search by

innobrain / laravel-onoffice-adapter

innobrain

Laravel package to joyfully interact with the onOffice API

Package info

github.com/innobraingmbh/laravel-onoffice-adapter

pkg:composer/innobrain/laravel-onoffice-adapter

Fund package maintenance!

Innobraingmbh

Statistics

Installs: 41 023

Dependents: 2

Suggesters: 0

Stars: 5

Open Issues: 9

v2.1.0 2026-09-14 05:53 UTC

README

Latest Version on Packagist Laravel Compatibility GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

A query builder for the onOffice API with an Eloquent-style interface.

View Full Documentation

Features

  • Query builder - select(), where(), orderBy(), limit(), offset()
  • Repositories - Estates, addresses, activities, appointments, tasks, search criteria, files, relations, and more
  • Pagination - get() reads every page; each() processes one page at a time
  • Middlewares - Run code before and after each request
  • Testing - Fake responses and record factories
  • Files - Upload, chunk, and link files to records

Installation

composer require innobrain/laravel-onoffice-adapter

Add your onOffice API credentials to .env:

ON_OFFICE_TOKEN=your-token
ON_OFFICE_SECRET=your-secret

To change retry settings or headers, publish the config file:

php artisan vendor:publish --tag="onoffice-adapter-config"

The package keeps one HTTP connection to the onOffice API open per PHP process and reuses it for every request, which skips the TCP and TLS handshake on all but the first call. Long-lived processes such as queue workers and Octane benefit most. If a stale connection is closed by the server, the request fails with a connection error and the retry settings above take over. Set reuse_connection to false in the config to open a fresh connection per request instead.

Usage

Basic Queries

use Innobrain\OnOfficeAdapter\Facades\EstateRepository;

// Get all estates
$estates = EstateRepository::query()->get();

// Find by ID
$estate = EstateRepository::query()->find(123);

// Get first result
$estate = EstateRepository::query()->first();

// Count results
$count = EstateRepository::query()->count();

Building Queries

Chain methods to filter, sort, and limit results:

$estates = EstateRepository::query()
    ->select(['Id', 'kaufpreis', 'lage'])
    ->where('status', 1)
    ->where('kaufpreis', '<', 500000)
    ->orderByDesc('kaufpreis')
    ->limit(10)
    ->get();

Available Methods

Method Description
select($fields) Fields to retrieve
where($field, $op, $value) Filter by condition
whereIn($field, $values) Filter by array of values
whereLike($field, $pattern) Pattern matching
whereBetween($field, $min, $max) Range filter
orderBy($field) Sort ascending
orderByDesc($field) Sort descending
limit($n) Max results
offset($n) Skip results

Large Datasets

each() processes one page per callback:

EstateRepository::query()
    ->each(function (array $estates) {
        foreach ($estates as $estate) {
            // Process chunk
        }
    });

A failed page throws OnOfficeException. No partial results. Chunks already passed to the callback are not rolled back.

Available Repositories

Repository Description
EstateRepository Real estate properties
AddressRepository Contacts and addresses
ActivityRepository Activity logs
ActionRepository Action kind types
AppointmentRepository Calendar appointments
TaskRepository Tasks
UserRepository onOffice users
SearchCriteriaRepository Buyer search profiles
FieldRepository Field metadata
FileRepository File uploads and downloads
FilterRepository Saved filters
RelationRepository Record relationships
SettingRepository System settings
MarketplaceRepository Marketplace integration
LinkRepository URL links
LogRepository Log entries
MacroRepository Macros
LastSeenRepository Recently viewed records

File Uploads

$tmpUploadId = FileRepository::upload()
    ->save(base64_encode($fileContent));

FileRepository::upload()->link($tmpUploadId, [
    'module' => 'estate',
    'relatedRecordId' => '12345',
]);

// Or upload in blocks and link in one call
FileRepository::upload()
    ->uploadInBlocks()
    ->saveAndLink(base64_encode($fileContent), [
        'module' => 'estate',
        'relatedRecordId' => '12345',
    ]);

Creating Activities

ActivityRepository::query()
    ->addressIds($recordIds)
    ->estateId($estateId)
    ->create([
        'datetime' => $event->getDateFormatted(),
        'actionkind' => 'Newsletter',
        'actiontype' => 'Hard Bounce',
        'note' => $message,
    ]);

Middlewares

Run code before each request:

use Innobrain\OnOfficeAdapter\Facades\BaseRepository;
use Innobrain\OnOfficeAdapter\Dtos\OnOfficeRequest;

BaseRepository::query()
    ->before(function (OnOfficeRequest $request) {
        Log::info('Sending request', ['request' => $request->toArray()]);
    })
    ->call(new OnOfficeRequest(/* ... */));

Debugging

// Dump and die
BaseRepository::query()->dd()->call(/* ... */);

// Dump without stopping
BaseRepository::query()->dump()->call(/* ... */);

// Record requests and responses
BaseRepository::record();
BaseRepository::query()->call(/* ... */);
$lastPair = BaseRepository::lastRecorded(); // [OnOfficeRequest, array]

Helpers

Default field lists and empty-value cleanup:

use Innobrain\OnOfficeAdapter\Services\OnOfficeService;

$estates = EstateRepository::query()
    ->select(OnOfficeService::DEFAULT_ESTATE_INFO_FIELDS)
    ->get();

// Remove fields with empty values ("", "0.00", [], null)
$estates = $estates->map(fn (array $estate) => clear_elements($estate));

Testing

Fake responses in tests:

use Innobrain\OnOfficeAdapter\Facades\EstateRepository;
use Innobrain\OnOfficeAdapter\Facades\Testing\RecordFactories\EstateFactory;

EstateRepository::fake(EstateRepository::response([
    EstateRepository::page(recordFactories: [
        EstateFactory::make()->id(1)->set('kaufpreis', 250000),
        EstateFactory::make()->id(2)->set('kaufpreis', 300000),
    ]),
]));

$estates = EstateRepository::query()->get();

expect($estates)->toHaveCount(2);
EstateRepository::assertSentCount(1);

Prevent Unstubbed Requests

EstateRepository::preventStrayRequests();
EstateRepository::fake(/* ... */);

// Any unstubbed request will throw StrayRequestException

Multiple Pages

EstateRepository::fake(EstateRepository::response([
    EstateRepository::page(recordFactories: [
        EstateFactory::make()->id(1),
    ]),
    EstateRepository::page(recordFactories: [
        EstateFactory::make()->id(2),
    ]),
]));

$estates = EstateRepository::query()->get();
expect($estates)->toHaveCount(2);

Sequences (Multiple Calls)

EstateRepository::fake([
    EstateRepository::response([/* first call */]),
    EstateRepository::response([/* second call */]),
]);

// Or repeat the same response
EstateRepository::fake(EstateRepository::sequence(
    EstateRepository::response([/* ... */]),
    times: 30,
));

See Testing for factories and assertions.

Development

composer test       # Run tests
composer analyse    # Static analysis (PHPStan)
composer format     # Code formatting (Laravel Pint)

Changelog

See CHANGELOG. For breaking changes, see UPGRADE.

Security Vulnerabilities

See the security policy.

Credits

License

MIT. See LICENSE.