PHPackages                             kompakt/b3d - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. kompakt/b3d

ActiveLibrary[API Development](/categories/api)

kompakt/b3d
===========

Berlin3 'Details' API Wrapper

1.0.0(7y ago)0166MITPHPPHP &gt;=5.4.0CI failing

Since Jun 11Pushed 2mo ago2 watchersCompare

[ Source](https://github.com/kompakt/b3d)[ Packagist](https://packagist.org/packages/kompakt/b3d)[ RSS](/packages/kompakt-b3d/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (7)Versions (2)Used By (0)

Kompakt\\B3d
============

[](#kompaktb3d)

Berlin3 [Details](http://berlin3.com) API Wrapper

Description
-----------

[](#description)

Get data from "Details" endpoints, optionally cache results, load full graph per "Details" schema, build canonical product representation and serialize result to xml files.

Installation
------------

[](#installation)

Through Composer:

- `composer require kompakt/b3d`

Introduction
------------

[](#introduction)

The Berlin3 [Details](http://berlin3.com) software for music businesses provides data access in the form of full table dumps. It's up to the user to construct the graph and assemble a data model for further usage. The following entities are available: releases, products, artists, labels, prices, product-tracks, tracks and stock. These entities build up the following structure:

```
+ release (1)
    + label (1)
        + artist (N)
    + product (N)
        + price (N)
        + stock (1)
            + account (N)
        + product-track (N)
            + track (N)

```

Library Features
----------------

[](#library-features)

- Data fetchers
- Data mappers
- Raw data caching
- In-memory graph loader
- Canonical product builder
- Canonical product serializer
- Extendable event-based architecture

Internally the data is mapped to temporary entity objects. These entities are then wired up by the graphloader. From there the graph is converted to a product-based datastructure in the from of canonical products. This draws a logical border to avoid "Details" interna to leak into your domain.

```
+ product (contains release-, artist- and labeldata)
    + price (N)
    + track (N)

```

### Fetching

[](#fetching)

```
use GuzzleHttp\Client;
use Kompakt\B3d\Details\Endpoint\Resource\Artist\Endpoint;

$artistEndpoint = new Endpoint(
    new Client(),
    '',
    ''
);

$rawArtistData = $artistEndpoint->fetchAll();
```

### Caching

[](#caching)

```
use Kompakt\B3d\Details\Endpoint\Cache\PhpFile\Serializer;
use Kompakt\B3d\Util\File\Writer;

$artistSerializer = new Serializer(
    new Writer(),
    'path/to/artist/data/file'
);

$artistSerializer->serialize($rawArtistData);
```

### Populating Entity Repository

[](#populating-entity-repository)

Populating from cache:

```
use Kompakt\B3d\Details\Endpoint\Resource\Artist\Mapper;
use Kompakt\B3d\Details\Entity\Artist;
use Kompakt\B3d\Details\Repository\ArtistRepository;
use Kompakt\B3d\Util\File\Reader;
use Kompakt\B3d\Details\Populator\Cache\PhpFile\Populator;

$artistPopulator = new Populator(
    new ArtistMapper(new Artist()),
    new ArtistRepository(),
    new Reader(),
    'path/to/artist/data/file'
);

$artistRepository = $artistPopulator->populate();
$artists = $artistRepository->getAll();
```

The individual parts can also be wired up to directly fetch and populate:

```
use Kompakt\B3d\Details\Endpoint\Resource\Artist\Mapper;
use Kompakt\B3d\Details\Entity\Artist;
use Kompakt\B3d\Details\Repository\ArtistRepository;
use Kompakt\B3d\Details\Populator\Endpoint\Populator;

$artistPopulator = new Populator(
    new ArtistMapper(new Artist()),
    new ArtistRepository(),
    $artistEndpoint
);
```

Loading the Graph
-----------------

[](#loading-the-graph)

```
use Kompakt\B3d\Details\Graph\Loader as GraphLoader;

$graphLoader = new GraphLoader(
    $artistPopulator,
    $labelPopulator,
    $pricePopulator,
    $productPopulator,
    $productTrackPopulator,
    $releasePopulator,
    $trackPopulator
);

$releaseRepository = $graphLoader->load();
```

Building and Serializing Canonical Products
-------------------------------------------

[](#building-and-serializing-canonical-products)

```
use Kompakt\B3d\Canonical\Dom\Product\Builder as CanonicalProductDomBuilder;
use Kompakt\B3d\Canonical\Entity\Price as CanonicalPrice;
use Kompakt\B3d\Canonical\Entity\Product as CanonicalProduct;
use Kompakt\B3d\Canonical\Entity\Track as CanonicalTrack;
use Kompakt\B3d\Canonical\Converter\Details\ConverterRunner;
use Kompakt\B3d\Canonical\Converter\Details\Product as CanonicalProductConverter;
use Kompakt\B3d\Canonical\Converter\Details\Subscriber\XmlSerializer as XmlSerializerSubscriber;
use Kompakt\B3d\Util\File\Writer;
use Kompakt\CollectionRunner\EventNames;
use Kompakt\CollectionRunner\Runner as CollectionRunner;
use Symfony\Component\EventDispatcher\EventDispatcher;

$dispatcher = new EventDispatcher();
$eventNames = new EventNames();
$collectionRunner = new CollectionRunner($dispatcher, $eventNames);

$canonicalProductConverter = new CanonicalProductConverter(
    new CanonicalProduct(),
    new CanonicalTrack(),
    new CanonicalPrice()
);

$canonicalProductXmlSerializer = new CanonicalProductXmlSerializer(
    new CanonicalProductDomBuilder(),
    new Writer(),
    'path/to/xml/output/dir'
);

$serializerSubscriber = new XmlSerializerSubscriber(
    $dispatcher,
    $eventNames,
    $canonicalProductXmlSerializer
);

$converterRunner = new ConverterRunner(
    $collectionRunner,
    $graphLoader,
    $canonicalProductConverter
);

$serializerSubscriber->activate();
$converterRunner->load();
$converterRunner->run();
```

Of course, you don't necessarily need to serialize the canonical products. You could omit `XmlSerializerSubscriber` and write your own event listener to directly save the data into a database

Populating Canonical Product Repository from serialized XML
-----------------------------------------------------------

[](#populating-canonical-product-repository-from-serialized-xml)

```
use Kompakt\B3d\Canonical\Dom\Product\Mapper as DomProductMapper;
use Kompakt\B3d\Canonical\Entity\Price;
use Kompakt\B3d\Canonical\Entity\Product;
use Kompakt\B3d\Canonical\Entity\Track;
use Kompakt\B3d\Canonical\Populator\Xml\Subscriber\Product as Populator;
use Kompakt\B3d\Canonical\Repository\ProductRepository;
use Kompakt\B3d\Canonical\Unserializer\Xml\Product as Unserializer;
use Kompakt\B3d\Util\Dom\Loader as DomLoader;
use Kompakt\B3d\Util\File\Reader;
use Kompakt\DirectoryRunner\Runner;
use Kompakt\DirectoryRunner\EventNames;
use Kompakt\DirectoryRunner\Subscriber\Debugger;
use Symfony\Component\EventDispatcher\EventDispatcher;

$dispatcher = new EventDispatcher();
$eventNames = new EventNames();
$fileReader = new Reader();
$domLoader = new DomLoader();

$runner = new Runner(
    $dispatcher,
    $eventNames,
    $canonicalProductDirPathname
);

$price = new Price();
$product = new Product();
$track = new Track();
$domMapper = new DomProductMapper($product, $track, $price);
$repository = new ProductRepository();

$unserializer = new Unserializer(
    $fileReader,
    $domLoader,
    $domMapper
);

$populator = new Populator(
    $dispatcher,
    $eventNames,
    $unserializer,
    $repository
);

$populator->activate();
$runner->run();

foreach ($repository->getAll() as $product)
{
    echo sprintf("%s\n", $product->getReleaseTitle());

    foreach ($product->getTracks() as $track)
    {
        echo sprintf(">> %s\n", $track->getTitle());
    }
}
```

Fetching Stock
--------------

[](#fetching-stock)

Once you have your products in place, you can fetch stocklevels. Be aware that the API returns a maximum of 200 stock items per request:

```
use GuzzleHttp\Client;
use Kompakt\B3d\Details\Endpoint\Resource\Stock\Endpoint as StockEndpoint;
use Kompakt\B3d\Details\Endpoint\Cache\PhpFile\Serializer as PhpFileSerializer;
use Kompakt\B3d\Util\File\Writer;
use Symfony\Component\Stopwatch\Stopwatch;

$stockEndpoint = new StockEndpoint(
    new Client(),
    '',
    ''
);

$stockEndpoint->fetch(['uuid-1', 'uuid-2']);
```

Passing Orders To Details
-------------------------

[](#passing-orders-to-details)

```
use GuzzleHttp\Client;
use Kompakt\B3d\Details\Endpoint\Resource\Order\Endpoint;

$orderEndpoint = new Endpoint(
    new Client(),
    '',
    ''
);

$orderData = [
    ...
];

$itemData = [
    ...
];

$orderEndpoint->create($orderData, $itemData);
```

Working Examples
----------------

[](#working-examples)

- `cp example/config.php.dist config.php`
- Adjust `config.php` as needed

License
-------

[](#license)

kompakt/b3d is licensed under the MIT license - see the LICENSE file for details

###  Health Score

36

—

LowBetter than 82% of packages

Maintenance58

Moderate activity, may be stable

Popularity12

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity57

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

2895d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/2da6dbd345cdda268ff447c0446b142346c03ab4c0bc13e3283369c458d57912?d=identicon)[kompakt](/maintainers/kompakt)

---

Top Contributors

[![sirprize](https://avatars.githubusercontent.com/u/81617?v=4)](https://github.com/sirprize "sirprize (83 commits)")

---

Tags

ERPmusic

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/kompakt-b3d/health.svg)

```
[![Health](https://phpackages.com/badges/kompakt-b3d/health.svg)](https://phpackages.com/packages/kompakt-b3d)
```

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M651](/packages/sylius-sylius)[tencentcloud/tencentcloud-sdk-php

TencentCloudApi php sdk

3731.2M42](/packages/tencentcloud-tencentcloud-sdk-php)[aerni/laravel-spotify

A Laravel wrapper for the Spotify Web API

209145.6k](/packages/aerni-laravel-spotify)[currency-cloud/client

A PHP library which implements the complete functionality of v2 of the The Currency Cloud API.

17327.2k](/packages/currency-cloud-client)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
