承接 baraja-core/heureka-feed 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

baraja-core/heureka-feed

Composer 安装命令:

composer require baraja-core/heureka-feed

包简介

Smart Heureka feed adapter.

README 文档

README

Smart PHP library for generating valid Heureka.cz XML product feeds. The package provides automatic feed generation, category management, product validation, and seamless integration with Nette Framework.

🎯 Key Principles

  • Automatic feed generation at the /xml/heureka-feed.xml endpoint
  • Built-in category management with official Heureka category tree support
  • Strict input validation for all product attributes (EAN-13, ISBN-10/13, URLs, etc.)
  • Support for all major Czech delivery providers (PPL, DPD, Zasilkovna, GLS, etc.)
  • Caching layer for category data to minimize external API calls
  • Extensible architecture with custom description renderers and product loaders
  • Full Nette Framework integration via DIC extension

🏗️ Architecture

The package follows a clean separation of concerns with the following main components:

┌─────────────────────────────────────────────────────────────────┐
│                    HeurekaFeedExtension                         │
│              (Nette DI Container Extension)                     │
└─────────────────────┬───────────────────────────────────────────┘
                      │ registers
                      ▼
┌─────────────────────────────────────────────────────────────────┐
│                      HeurekaManager                             │
│                   (Main Entry Point)                            │
└─────────────────────┬───────────────────────────────────────────┘
                      │ uses
                      ▼
┌─────────────────────────────────────────────────────────────────┐
│                       FeedRenderer                              │
│              (XML Output Generation)                            │
├─────────────────────┬───────────────────────────────────────────┤
│                     │                                           │
│   ┌─────────────────▼─────────────────┐                         │
│   │        ProductLoader              │◄──── Your Implementation│
│   │         (Interface)               │                         │
│   └─────────────────┬─────────────────┘                         │
│                     │ returns                                   │
│   ┌─────────────────▼─────────────────┐                         │
│   │       HeurekaProduct[]            │                         │
│   │          (Entities)               │                         │
│   └───────────────────────────────────┘                         │
│                                                                 │
│   ┌───────────────────────────────────┐                         │
│   │     DescriptionRenderer           │◄──── Optional           │
│   │         (Interface)               │                         │
│   └───────────────────────────────────┘                         │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│                     CategoryManager                             │
│        (Heureka Category Tree Management)                       │
├─────────────────────────────────────────────────────────────────┤
│  • Fetches official category XML from Heureka                   │
│  • Caches data for 8 hours                                      │
│  • Provides tree-structured selectbox data                      │
└─────────────────────────────────────────────────────────────────┘

📦 Components Overview

Component Description
HeurekaFeedExtension Nette DI extension that registers all services and sets up automatic feed endpoint
HeurekaManager Main orchestrator that triggers feed rendering
FeedRenderer Converts product data to valid Heureka XML format
ProductLoader Interface you implement to provide your products
CategoryManager Manages Heureka's official category tree with caching
HeurekaProduct Entity representing a single product with all Heureka attributes
Category Entity representing a Heureka category with parent hierarchy
Delivery Entity representing delivery options with predefined carrier constants
DescriptionRenderer Interface for custom product description formatting
Helpers Utility class with EAN-13 and ISBN-10/13 validation methods

📦 Installation

It's best to use Composer for installation, and you can also find the package on Packagist and GitHub.

To install, simply use the command:

$ composer require baraja-core/heureka-feed

You can use the package manually by creating an instance of the internal classes, or register a DIC extension to link the services directly to the Nette Framework.

Nette Framework Integration

Register the extension in your config.neon:

extensions:
    heurekaFeed: Baraja\Heureka\HeurekaFeedExtension

The extension automatically:

  • Registers HeurekaManager, CategoryManager, and FeedRenderer as services
  • Sets up the feed endpoint at /xml/heureka-feed.xml
  • Configures Markdown description renderer if baraja-core/markdown-latte-filter is available

🚀 Basic Usage

1. Implement the ProductLoader Interface

Create a class that implements ProductLoader to provide your products:

<?php

declare(strict_types=1);

namespace App\Services;

use Baraja\Heureka\ProductLoader;
use Baraja\Heureka\HeurekaProduct;
use Baraja\Heureka\CategoryManager;
use Baraja\Heureka\Delivery;

final class MyProductLoader implements ProductLoader
{
    public function __construct(
        private CategoryManager $categoryManager,
        private ProductRepository $productRepository,
    ) {
    }

    /**
     * @return HeurekaProduct[]
     */
    public function getProducts(): array
    {
        $products = [];

        foreach ($this->productRepository->findAllActive() as $product) {
            $heurekaProduct = new HeurekaProduct(
                itemId: (string) $product->getId(),
                product: $product->getName(),
                productName: $product->getFullName(),
                url: 'https://example.com/product/' . $product->getSlug(),
                priceVat: $product->getPrice(),
                category: $this->categoryManager->getCategory($product->getHeurekaCategoryId()),
                manufacturer: $product->getManufacturer(),
            );

            $heurekaProduct->setDescription($product->getDescription());
            $heurekaProduct->setImgUrl($product->getMainImageUrl());
            $heurekaProduct->setDeliveryDate($product->getDeliveryDays());

            if ($product->getEan() !== null) {
                $heurekaProduct->setEan($product->getEan());
            }

            $heurekaProduct->addDelivery(new Delivery(Delivery::PPL, 99.0));
            $heurekaProduct->addDelivery(new Delivery(Delivery::ZASILKOVNA, 59.0, 79.0));

            $products[] = $heurekaProduct;
        }

        return $products;
    }
}

2. Register Your ProductLoader

In your config.neon:

services:
    - App\Services\MyProductLoader

The FeedRenderer will automatically detect and use your ProductLoader implementation.

3. Access the Feed

Once configured, the XML feed is automatically available at:

https://your-domain.com/xml/heureka-feed.xml

📋 HeurekaProduct Entity

The HeurekaProduct entity supports all standard Heureka feed attributes:

Required Attributes (Constructor)

Attribute Type Description
itemId string Unique product identifier (max 36 chars, alphanumeric with - and _)
product string Product name for matching (max 200 chars)
productName string Exact product name displayed to users (max 200 chars)
url string Absolute URL to product detail page (max 300 chars)
priceVat float Price including VAT
category Category Heureka category entity
manufacturer string Manufacturer/brand name

Optional Attributes (Setters)

$product->setDescription('Product description text');
$product->setImgUrl('https://example.com/image.jpg');
$product->setVideoUrl('https://youtube.com/watch?v=xxx');
$product->addImgUrlAlternative('https://example.com/image2.jpg');
$product->setVat(21.0);
$product->setDeliveryDate(3); // days or DateTime instance
$product->setEan('1234567890123');
$product->setIsbn('978-3-16-148410-0');
$product->setProductNo('SKU123');
$product->setHeurekaCpc(1.5); // max 1000
$product->setParams(['Color' => 'Red', 'Size' => 'XL', 'Wireless' => true]);
$product->setItemType('new');
$product->addAccessory('accessory-item-id');
$product->addCustomTag('CUSTOM_TAG', 'value');

Image Requirements

  • Minimum size: 20x20 pixels
  • Recommended size: 175x175 pixels
  • Maximum size: 4096x4096 pixels (2 MB)
  • Video URL: Only YouTube links are supported (youtube.com or yt.be domains)

Parameter Handling

Parameters are automatically converted:

  • Boolean values become "ano" / "ne"
  • Numeric values must include units (e.g., "100 g", not just 100)
$product->setParams([
    'Color' => 'Blue',
    'Weight' => '500 g',
    'Waterproof' => true,  // becomes "ano"
    'Bluetooth' => false,  // becomes "ne"
]);

🚚 Delivery Options

The Delivery entity supports all major Czech carriers:

use Baraja\Heureka\Delivery;

// Basic delivery
$delivery = new Delivery(Delivery::PPL, 99.0);

// Delivery with COD (cash on delivery) price
$delivery = new Delivery(Delivery::ZASILKOVNA, 59.0, 79.0);

$product->addDelivery($delivery);

Supported Carriers

Constant Carrier
CESKA_POSTA Ceska posta - Balik Do ruky
CESKA_POSTA_NAPOSTU_DEPOTAPI Ceska posta - Balik Na postu
CESKA_POSTA_DOPORUCENA_ZASILKA Ceska posta - Doporucena zasilka
PPL PPL
DPD DPD
DPD_PICKUP DPD Pickup
DHL DHL
GLS GLS
GEIS Geis
ZASILKOVNA Zasilkovna
BALIKOVNA_DEPOTAPI Balikovna
UPS UPS
FEDEX FedEx
TNT TNT
TOPTRANS TOPTRANS
WEDO WeDo (IN TIME & Ulozhenka)
VLASTNI_PREPRAVA Custom delivery
FOFR FOFR
DSV DSV
HDS HDS
GEBRUDER_WEISS Gebruder Weiss
SEEGMULLER Seegmuller
RABEN_LOGISTICS Raben Logistics
CSAD_LOGISTIK_OSTRAVA CSAD Logistik Ostrava

📁 Category Management

The CategoryManager provides access to Heureka's official category tree:

use Baraja\Heureka\CategoryManager;

class MyService
{
    public function __construct(
        private CategoryManager $categoryManager,
    ) {
    }

    public function example(): void
    {
        // Get a specific category by ID
        $category = $this->categoryManager->getCategory(123);

        // Get all categories as flat array
        $allCategories = $this->categoryManager->getCategories();

        // Get categories formatted for selectbox (id => name)
        $selectableCategories = $this->categoryManager->getSelectableCategories();

        // Get categories as tree-structured selectbox (with indentation)
        $selectboxTree = $this->categoryManager->getCategoriesSelectbox();
    }
}

Category Entity

$category->getId();           // int - Category ID
$category->getName();         // string - Category name
$category->getParent();       // ?Category - Parent category
$category->getParentId();     // ?int - Parent category ID
$category->getCategoryText(); // string - Full path (e.g., "Heureka.cz | Electronics | Phones")
$category->getParentsPath();  // array - [id => name] of all parents

Custom Category Feed URL

By default, categories are fetched from https://www.heureka.cz/direct/xml-export/shops/heureka-sekce.xml. You can change this:

$categoryManager->setFeedUrl('https://custom-feed-url.com/categories.xml');

Caching

  • Category feed is cached for 8 hours
  • Selectbox tree is cached for 1 hour
  • Uses Nette Caching with configurable storage

🎨 Custom Description Renderer

Implement DescriptionRenderer to customize how product descriptions are processed:

use Baraja\Heureka\DescriptionRenderer;

final class HtmlStripperDescriptionRenderer implements DescriptionRenderer
{
    public function render(string $haystack): string
    {
        return strip_tags($haystack);
    }
}

Register your implementation:

services:
    - HtmlStripperDescriptionRenderer

Then set it on the FeedRenderer:

$feedRenderer->setDescriptionRenderer($myRenderer);

Built-in Markdown Renderer

If baraja-core/markdown-latte-filter is installed, the BarajaMarkdownDescriptionRenderer is automatically registered. It converts Markdown to plain text (strips HTML tags after rendering).

🔧 Validation Helpers

The Helpers class provides validation utilities:

use Baraja\Heureka\Helpers;

// Validate EAN-13 barcode
Helpers::validateEAN13('1234567890123'); // bool

// Validate ISBN-10
Helpers::isValidIsbn10('0-306-40615-2'); // bool

// Validate ISBN-13
Helpers::isValidIsbn13('978-3-16-148410-0'); // bool

These validators are automatically used when setting EAN or ISBN on HeurekaProduct and will throw InvalidArgumentException for invalid values.

🔍 Generated XML Structure

The generated feed follows Heureka's XML specification:

<?xml version="1.0" encoding="utf-8"?>
<SHOP>
    <SHOPITEM>
        <ITEM_ID>product-123</ITEM_ID>
        <PRODUCT>Product Name</PRODUCT>
        <PRODUCTNAME>Full Product Name</PRODUCTNAME>
        <DESCRIPTION>Product description</DESCRIPTION>
        <URL>https://example.com/product/123</URL>
        <IMGURL>https://example.com/images/product.jpg</IMGURL>
        <IMGURL_ALTERNATIVE>https://example.com/images/product-2.jpg</IMGURL_ALTERNATIVE>
        <PRICE_VAT>1299</PRICE_VAT>
        <VAT>21</VAT>
        <MANUFACTURER>Brand Name</MANUFACTURER>
        <CATEGORYTEXT>Heureka.cz | Electronics | Phones</CATEGORYTEXT>
        <DELIVERY_DATE>3</DELIVERY_DATE>
        <EAN>1234567890123</EAN>
        <PARAM>
            <PARAM_NAME>Color</PARAM_NAME>
            <VAL>Red</VAL>
        </PARAM>
        <DELIVERY>
            <DELIVERY_ID>PPL</DELIVERY_ID>
            <DELIVERY_PRICE>99</DELIVERY_PRICE>
        </DELIVERY>
        <DELIVERY>
            <DELIVERY_ID>ZASILKOVNA</DELIVERY_ID>
            <DELIVERY_PRICE>59</DELIVERY_PRICE>
            <DELIVERY_PRICE_COD>79</DELIVERY_PRICE_COD>
        </DELIVERY>
    </SHOPITEM>
</SHOP>

⚠️ Error Handling

The package performs extensive validation and throws exceptions for invalid data:

  • InvalidArgumentException - For invalid attribute values (URLs, EAN, ISBN, lengths, etc.)
  • LogicException - For duplicate ItemId values in the feed
  • RuntimeException - When ProductLoader is not configured

All validation errors include descriptive messages to help identify the issue.

📝 Manual Usage (Without Nette)

use Baraja\Heureka\FeedRenderer;
use Baraja\Heureka\CategoryManager;
use Nette\Http\Response;
use Nette\Caching\Storages\MemoryStorage;

// Create dependencies
$storage = new MemoryStorage();
$response = new Response();
$categoryManager = new CategoryManager($storage);

// Create renderer
$feedRenderer = new FeedRenderer($response);
$feedRenderer->setProductLoader(new MyProductLoader($categoryManager));

// Render feed
$feedRenderer->render();

👤 Author

Jan Barasek - https://baraja.cz

📄 License

baraja-core/heureka-feed is licensed under the MIT license. See the LICENSE file for more details.

baraja-core/heureka-feed 适用场景与选型建议

baraja-core/heureka-feed 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 21.81k 次下载、GitHub Stars 达 3, 最近一次更新时间为 2021 年 01 月 02 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 baraja-core/heureka-feed 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 baraja-core/heureka-feed 我们能提供哪些服务?
定制开发 / 二次开发

基于 baraja-core/heureka-feed 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 21.81k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 3
  • 点击次数: 3
  • 依赖项目数: 2
  • 推荐数: 0

GitHub 信息

  • Stars: 3
  • Watchers: 2
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: Unknown
  • 更新时间: 2021-01-02