A typed, framework-agnostic SDK for the Luceed DataSnap REST API.
Luceed endpoints are powerful but inconsistent across modules:
- mixed URL casing
- path arrays like
[0,100] D/Nbooleans- varied result payload shapes (
["uid"],[true],[[true,true]],["OK"])
This SDK standardizes those patterns with typed clients, normalized responses, and reusable transport/auth layers.
- PSR-18 HTTP client support (works with Guzzle and others)
- PSR-17 request/stream factory support
- Pluggable auth (
Basic,Bearer, custom headers, query key) - Typed domain clients for core Luceed modules
RawClientfallback for any custom endpoint- DTOs for common write operations (
ArticleUpsert,PartnerUpsert,UserUpsert,DocumentFile) - Works in Laravel, OpenCart, and plain PHP
composer require agmedia/luceed-sdkTypical runtime dependencies:
composer require guzzlehttp/guzzle nyholm/psr7<?php
use Agmedia\Luceed\Auth\BasicAuth;
use Agmedia\Luceed\LuceedConfig;
use Agmedia\Luceed\LuceedFactory;
use GuzzleHttp\Client as GuzzleClient;
use Nyholm\Psr7\Factory\Psr17Factory;
$psr17 = new Psr17Factory();
$client = LuceedFactory::fromPsr(
config: new LuceedConfig('https://your-luceed-host/datasnap/rest'),
httpClient: new GuzzleClient(),
requestFactory: $psr17,
streamFactory: $psr17,
authenticator: new BasicAuth('username', 'password')
);
$artikli = $client->artikli()->getBySifra('TVSO26BX320B');
$partneri = $client->partneri()->getByOib('12345678911');
foreach ($artikli as $artikl) {
echo sprintf(
"Artikl: %s | Naziv: %s | Barcode: %s\n",
$artikl->code ?? '-',
$artikl->name ?? '-',
$artikl->barcode ?? '-'
);
}
foreach ($partneri as $partner) {
echo sprintf(
"Partner: %s | Naziv: %s | OIB: %s\n",
$partner->code ?? '-',
$partner->name ?? '-',
$partner->oib ?? '-'
);
}<?php
namespace App\Providers;
use Agmedia\Luceed\Auth\BasicAuth;
use Agmedia\Luceed\LuceedClient;
use Agmedia\Luceed\LuceedConfig;
use Agmedia\Luceed\LuceedFactory;
use GuzzleHttp\Client as GuzzleClient;
use Illuminate\Support\ServiceProvider;
use Nyholm\Psr7\Factory\Psr17Factory;
final class LuceedServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(LuceedClient::class, function () {
$psr17 = new Psr17Factory();
return LuceedFactory::fromPsr(
config: new LuceedConfig(config('services.luceed.base_uri')),
httpClient: new GuzzleClient(),
requestFactory: $psr17,
streamFactory: $psr17,
authenticator: new BasicAuth(
config('services.luceed.username'),
config('services.luceed.password')
)
);
});
}
}config/services.php
'luceed' => [
'base_uri' => env('LUCEED_BASE_URI'),
'username' => env('LUCEED_USERNAME'),
'password' => env('LUCEED_PASSWORD'),
],Example usage in controller/service:
<?php
namespace App\Http\Controllers;
use Agmedia\Luceed\LuceedClient;
use Illuminate\Http\JsonResponse;
final class LuceedDemoController
{
public function __invoke(LuceedClient $client): JsonResponse
{
$artikli = $client->artikli()->getBySifra('TVSO26BX320B');
$partneri = $client->partneri()->getByOib('12345678911');
return response()->json([
'artikli_count' => count($artikli),
'partneri_count' => count($partneri),
'first_artikl' => $artikli[0]->extra ?? null,
'first_partner' => $partneri[0]->extra ?? null,
]);
}
}$psr17 = new \Nyholm\Psr7\Factory\Psr17Factory();
$client = \Agmedia\Luceed\LuceedFactory::fromPsr(
config: new \Agmedia\Luceed\LuceedConfig($this->config->get('luceed_base_uri')),
httpClient: new \GuzzleHttp\Client(),
requestFactory: $psr17,
streamFactory: $psr17,
authenticator: new \Agmedia\Luceed\Auth\BasicAuth(
$this->config->get('luceed_username'),
$this->config->get('luceed_password')
)
);
$artikli = $client->artikli()->getBySifra('TVSO26BX320B');
$partneri = $client->partneri()->getByOib('12345678911');
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode([
'artikli_count' => count($artikli),
'partneri_count' => count($partneri),
'first_artikl' => $artikli ? $artikli[0]->extra : null,
'first_partner' => $partneri ? $partneri[0]->extra : null,
]));| Module | Client Method |
|---|---|
| Artikli | $client->artikli() |
| Partneri | $client->partneri() |
| Users | $client->users() |
| Sifrarnici | $client->sifrarnici() |
| Mjesta | $client->mjesta() |
| Skladista | $client->skladista() |
| Grupe artikala | $client->grupeArtikala() |
| Robne marke | $client->robneMarke() |
| Vrste plaćanja | $client->vrstePlacanja() |
| Prijevodi | $client->prijevodi() |
| Varijante | $client->varijante() |
| Cjenik | $client->cjenik() |
| Cjenik partner | $client->cjenikPartner() |
| Module | Client Method |
|---|---|
| Stanje zalihe | $client->stanjeZalihe() |
| Stanje zalihe dobavljača | $client->stanjeZaliheDobavljaci() |
| Stanje po serijskim brojevima | $client->stanjeZaliheSerijski() |
| Cijene | $client->cijene() |
| Artikli popusti | $client->artikliPopusti() |
| Prodajne akcije | $client->prodajneAkcije() |
| Akcije | $client->akcije() |
| Bodovi | $client->bodovi() |
| Module | Client Method |
|---|---|
| Nalozi prodaje | $client->naloziProdaje() |
| Nalozi prodaje dokumenti isporuke | $client->naloziProdajeDokumentiIsporuke() |
| Nalozi prodaje prijevoznice | $client->naloziProdajePrijevoznice() |
| Narudžbe | $client->narudzbe() |
| Nalozi povrata | $client->naloziPovrata() |
| Nalozi proizvodnje | $client->naloziProizvodnje() |
| MP računi | $client->mPracuni() |
| VP računi | $client->vPracuni() |
| Računi predujma | $client->racuniPredujma() |
| Skladišni dokumenti | $client->skladisniDokumenti() |
| Document manager | $client->documentManager() |
| Bundle artikl | $client->bundleArtikl() |
| Module | Client Method |
|---|---|
| Radni nalozi | $client->radniNalozi() |
| CRM | $client->crm() |
| Predmeti | $client->predmeti() |
| Statusi | $client->statusi() |
| MP obračun | $client->mpObracun() |
| Prodajni uvjeti | $client->prodajniUvjeti() |
| Tečajna lista | $client->tecajnaLista() |
| Knjiženje | $client->knjizenje() |
| URA | $client->ura() |
| Interna razmjena | $client->internaRazmjena() |
| Hotel | $client->hotel() |
| Hotel rezervacije | $client->hotelRezervacije() |
| Poklon bonovi | $client->poklonBonovi() |
| Module | Client Method |
|---|---|
| Any custom endpoint | $client->raw() |
use Agmedia\Luceed\Domain\Artikli\ArticleUpsert;
$article = ArticleUpsert::make(code: 'A100', name: 'Demo artikel')
->withBarcode('3850000000012')
->withEnabled(true)
->withMpc(99.90);
$result = $client->artikli()->save([$article]);use Agmedia\Luceed\Domain\Users\UserUpsert;
$user = UserUpsert::make(username: 'test_korisnik', userB2B: 'u-123')
->withName('Test', 'Korisnik')
->withEmail('[email protected]')
->withFields([
'service_group' => 'S',
'mjesto' => '10000',
]);
$result = $client->users()->save([$user]);use Agmedia\Luceed\Domain\DocumentManager\DocumentFile;
$file = DocumentFile::fromBase64(
name: 'Racun PDF',
filename: 'racun-1001.pdf',
contentBase64: base64_encode(file_get_contents('/path/racun-1001.pdf')),
contentType: 'dctPDF'
)->withFields([
'tip_veze' => 'Artikli',
'doc_uid' => '67355-42',
]);
$result = $client->documentManager()->save([$file]);NoAuthBasicAuthBearerTokenAuthHeaderAuthQueryKeyAuth
If your Luceed host uses a custom auth header/query format, use HeaderAuth or QueryKeyAuth.
Luceed response payloads vary per module. This SDK normalizes the most common patterns and exposes:
- strongly typed DTOs for key entities
OperationResultfor write endpointsDataRecordfor flexible read payloads where schema differs heavily between installations
composer validate --strict
composer testIn offline environments, dependency install and PHPUnit execution may fail due Packagist reachability.
MIT — see LICENSE