PimCore is an open-source platform that combines CMS, PIM, DAM and e-commerce capabilities in one system. It is less known than Akeneo in PIM circles but offers something Akeneo does not: a full content management layer alongside product data. I show the architecture, object classes that define the data model, the Data Hub GraphQL API, and integration with Magento 2.
PimCore vs Akeneo – key differences
| Feature | PimCore | Akeneo CE |
|---|---|---|
| PIM (product data) | Yes | Yes |
| DAM (digital assets) | Yes – built in | No (paid add-on) |
| CMS (pages, content) | Yes – full CMS | No |
| E-commerce layer | Yes (PimCore Commerce) | No |
| GraphQL API | Data Hub (free) | Paid add-on |
| Technology | PHP/Symfony | PHP/Symfony |
| Learning curve | Steeper | Gentler |
Data Objects – custom data model without writing PHP
PimCore Object Classes define your data model through the admin panel. You create classes with fields (text, select, relation, asset, localised fields) and PimCore generates PHP classes automatically. No schema migrations, no PHP model files to write.
<?php
// PimCore auto-generates model classes in /var/classes/DataObject/
// You use them like regular PHP objects
use Pimcore\Model\DataObject\Product;
// Fetch a product by ID
$product = Product::getById(123);
// Fetch with localised data
$product = Product::getById(123, ['force' => true]);
echo $product->getName(); // name in current locale
echo $product->getName('pl'); // name in Polish
echo $product->getName('en'); // name in English
// Get related asset
$mainImage = $product->getMainImage();
echo $mainImage?->getFullPath();
// Fetch a list with filters
$products = new Product\Listing();
$products->setCondition('status = ?', ['active']);
$products->setOrderKey('name');
$products->setOrder('asc');
$products->setLimit(100);
foreach ($products as $product) {
echo $product->getSku() . ': ' . $product->getName() . PHP_EOL;
}
Data Hub – GraphQL API configuration
PimCore Data Hub lets you create a GraphQL API endpoint through the admin panel in minutes – select which classes and fields to expose, configure access rules, and the endpoint is ready.
# Data Hub GraphQL endpoint
# Configured in: Settings -> Data Hub -> New Configuration
# Example query once configured:
query {
getProductListing(
filter: "{\"status\": {\"$eq\": \"active\"}}",
first: 10,
after: "cursor_value"
) {
edges {
node {
id
sku
name(language: "en")
price
mainImage { fullpath }
categories {
edges {
node { name(language: "en") }
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
Integrating PimCore with Magento 2
<?php
declare(strict_types=1);
namespace Vendor\PimcoreConnector\Model;
use GuzzleHttp\Client;
class PimcoreClient
{
private Client $httpClient;
public function __construct(
private string $endpoint,
private string $apiKey
) {
$this->httpClient = new Client(['base_uri' => $endpoint]);
}
public function getProducts(int $first = 100, ?string $after = null): array
{
$variables = ['first' => $first];
if ($after !== null) $variables['after'] = $after;
$response = $this->httpClient->post('', [
'headers' => [
'X-API-Key' => $this->apiKey,
'Content-Type' => 'application/json',
],
'json' => [
'query' => $this->getProductListingQuery(),
'variables' => $variables,
],
]);
return json_decode($response->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR);
}
private function getProductListingQuery(): string
{
return '
query GetProducts($first: Int, $after: String) {
getProductListing(first: $first, after: $after,
filter: "{\"status\": {\"$eq\": \"active\"}}") {
edges {
node {
id sku
name(language: "pl")
price
mainImage { fullpath }
}
}
pageInfo { hasNextPage endCursor }
}
}
';
}
}
// Sync cron
class SyncFromPimcore
{
public function execute(): void
{
$after = null;
do {
$data = $this->pimcoreClient->getProducts(100, $after);
$listing = $data['data']['getProductListing'];
$edges = $listing['edges'];
$pageInfo = $listing['pageInfo'];
foreach ($edges as $edge) {
$this->syncProduct($edge['node']);
}
$after = $pageInfo['hasNextPage'] ? $pageInfo['endCursor'] : null;
} while ($after !== null);
}
}
Summary
PimCore makes sense for projects that need both PIM and CMS in one system – managing product data and editorial content with shared assets. The Data Hub GraphQL API is a strong differentiator versus Akeneo CE. The integration pattern with Magento 2 is similar to Akeneo: pull data via the API, map to Magento attributes, sync on cron. The main investment is learning the PimCore object model and Data Hub configuration.
