Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Bmecat Laravel Package

se/bmecat

PHP/Laravel package for working with BMEcat, the XML format used to exchange electronic product catalog data. Read and write catalog documents containing products, prices, units, suppliers and classifications, making it easier to import or export procurement data in PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

The package is a small, framework-agnostic library — there is no Laravel service provider, facade, or config file. Treat it like a low-level XML builder you wrap yourself.

  1. Install it. The current release is 0.1.4, a patch that fixes namespace imports:

    composer require se/bmecat:0.1.4
    

    It is still pre-1.0, so treat the API as unstable and pin exactly. If you are upgrading from an earlier 0.1.x, re-check your use statements — the namespace fix may change class resolution.

  2. Read the source before the README. The README is thin; the real API surface is in src/ and the fixtures in tests/. You are looking for two things: the root document class and how elements are appended (builder methods vs. nested objects) and the serialization entry point (toXml(), asXml(), or a __toString).

  3. Sketch the smallest possible document to prove the API:

    $doc = new \Se\Bmecat\Bmecat();      // confirm real class name in src/
    $doc->addHeader($supplierName, $supplierId);
    $doc->addCatalog($catalogId, $catalogName);
    $doc->addProduct($sku, $title, $price, $currency);
    file_put_contents(storage_path('app/bmecat.xml'), $doc->toXml());
    
  4. Validate immediately against the BMEcat XSD (BMEcat 1.2 bmecat_1_2.xsd or 2005, depending on the version the package targets):

    xmllint --noout --schema bmecat_1_2.xsd storage/app/bmecat.xml
    

    Schema validation is the fastest feedback loop you have with a low-activity package.

  5. First real use case: a nightly export of your products table into a BMEcat file that a B2B customer's procurement system imports. Do not wire this into a controller — the package is CPU-light but I/O-heavy, so your first integration should be an Artisan command writing to Storage::disk('exports').

Implementation Patterns

Wrap the library in a single service class. Keep every reference to Se\Bmecat\* inside one class so a future fork/replacement is a one-file change:

// app/Services/BmecatExporter.php
class BmecatExporter
{
    public function export(Collection $products, CatalogConfig $config): string
    {
        $doc = new \Se\Bmecat\Bmecat();
        $doc->addHeader($config->supplierName, $config->supplierId);
        $doc->addCatalog($config->catalogId, $config->catalogName);

        foreach ($products as $product) {
            $doc->addProduct(
                $product->sku,
                $product->name,
                $this->price($product, $config),
                $config->currency,
            );
        }

        return $doc->toXml();
    }
}

Map Eloquent models through a DTO, never directly. BMEcat cares about element order, decimal formatting, and escaped entities — things Eloquent attributes don't guarantee. Convert Product → BmecatProductData (a readonly value object) and let the exporter consume only DTOs. This is also where you put default tax rates, price groups, and unit-of-measure mapping.

Use a queued job for the actual export, an Artisan command to schedule it.

// app/Console/Commands/ExportBmecat.php
Product::query()->chunkById(500, fn ($chunk) =>
    ExportBmecatJob::dispatch($chunk, $customerId)
);

Chunking matters because the package almost certainly builds a full in-memory tree — see the memory gotcha below.

Drive catalog configuration from config, not code. A config/bmecat.php with per-customer blocks (supplier ID, catalog ID, currency, price group, buyer ID) lets you support multiple B2B customers without branching. Store the generated filename and hash in a catalog_exports table for audit and re-download.

Compose documents from a domain catalog object. Keep your own Catalog aggregate (products, categories, classification codes) and have a thin BmecatRenderer translate it. This keeps BMEcat-version quirks out of your models and lets you add a JSON/CSV exporter later using the same aggregate.

Test with XML snapshots plus XSD validation. In a Pest/PHPUnit test, assert toXml() output validates against the bundled XSD (run xmllint in the test setup) and snapshot the normalized XML. That combination catches both "wrong data" and "wrong structure."

Gotchas and Tips

  • 0.1.4 only fixes namespace imports. It is not a feature release, but it is still pre-1.0 and low-activity. Pin exactly ("se/bmecat": "0.1.4") and do not assume future maintenance. If you upgraded from an earlier patch, run a smoke test that instantiates the root class and serializes a tiny document.
  • Expect to fork for modern PHP. The package is old and small; if you are on PHP 8.1+, check for type/each()/dynamic property issues before writing application code.
  • Element order is enforced by the XSD. BMEcat's schema uses xs:sequence, so header → catalog → products must be added in that order. If serialization fails validation, element ordering is almost always the cause — diff your output against a known-good fixture before suspecting data.
  • Escape user input yourself. Product names commonly contain &, <, and umlauts. Confirm whether the package uses DOMDocument or string concatenation; if it's the latter, run every free-text field through htmlspecialchars($v, ENT_XML1 | ENT_QUOTES, 'UTF-8').
  • Watch memory on large catalogs. A tree-of-objects builder will blow up around tens of thousands of products. Split exports into multiple documents (one per product category) or fork the serializer to use XMLWriter for streaming.
  • Decimal separators are a silent killer. BMEcat expects .-decimal prices with a defined currency; a localized 12,90 will either fail validation or import as the wrong price. Centralize price formatting in one method.
  • Likely missing features: MIME info, classification systems (eClass, UNSPSC), user-defined fields, and multilingual variants. Rather than hacking the core class, add an addRawXml(string $xml)-style escape hatch in your wrapper — or generate those fragments with DOMDocument and append them before serialization.
  • No built-in schema validation. Ship the XSD with your tests and validate in CI. A green PHPUnit suite without XSD validation is not a working BMEcat export.
  • Debug by dumping to disk, not by dd(). dd($doc) on a partially built document is unreadable; write toXml() to storage/app/tmp/bmecat.xml and inspect in an editor with a schema plugin.
  • Extension point: if you must extend, subclass the root builder and add your own add* methods, keeping the parent's element-append pattern. Avoid modifying vendor/ — a composer update will erase it.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource