akeneo/pim-community-dev
Development repository for Akeneo PIM, the open-source product information management platform. Contains the PIM source code in src/; use pim-community-standard to start a project. Uses CalVer versioning with no SemVer backwards compatibility guarantee.
First, the honest framing: akeneo/pim-community-dev is not a Laravel package. It is a standalone Symfony application (PHP 8.1–8.3, Doctrine, Twig, Elasticsearch, MySQL, RabbitMQ) and this repo is the development repo, not something you composer require into a Laravel app. Two legitimate ways a Laravel developer uses it day-to-day:
Minimal steps (integration path, recommended):
akeneo/pim-community-standard, not this repo. git clone → composer install → make dev (or docker build --target dev -t akeneo/pim-php-dev:master .), then bin/console pim:install. Needs MySQL 8.0.34+ (8.4 supported from v2026.4), Elasticsearch 8.17, RabbitMQ, Redis.bin/console akeneo:api:create-client style, or via the UI (Connect → API connections).$token = Http::asForm()->post("{$base}/api/oauth/v1/token", [
'grant_type' => 'password', 'client_id' => ..., 'client_secret' => ...,
'username' => ..., 'password' => ...,
])->json('access_token');
GET /api/rest/v1/products?search={"completeness":[{"operator":"=","value":100,"scope":"ecommerce"}]}&limit=100 and cache the JSON in a local table. That's your whole first week.Where to look first: src/Akeneo/Pim/Enrichment/Bundle/Controller/ExternalApi/ for the actual API surface, src/Akeneo/Pim/Structure/ for families/attributes, and config/packages/ for infrastructure wiring.
Treat the PIM as the system of record, Laravel as the system of use. Mirror only what you need (product identifiers, SKU, localized names, media URLs) into your own DB; never make a storefront request hit Akeneo synchronously.
Incremental sync via job + queue. Wrap the client in a AkeneoClient service with cached tokens (they expire ~1h), retry(3, 500) and rate limiting. Then:
// nightly delta
$since = Product::max('akeneo_updated_at');
$client->get('products', ['search' => json_encode(['updated' => [['operator' => '>', 'value' => $since]])]]);
Dispatch one queued job per chunk, upsert on identifier, store the raw payload in a JSON column for forward-compat.
Use search_after pagination, not page numbers. For 50K+ SKUs the offset pagination falls over; pagination_type=search_after with a cursor is the supported path, and bulk endpoints (/api/rest/v1/products-uuid collections, or the bulk POST/PATCH which returns a Location header) are the write path — poll the location until 201.
Event-driven instead of polling (where available). Akeneo's Events API lets you POST a subscription URL; deliveries are HMAC-signed (X-Akeneo-Request-Signature) — verify with hash_hmac('sha256', $rawBody, $secret) in a Laravel middleware, then push to a queue. Check availability for your exact version; it isn't in every CalVer build.
Data modelling comes first, code second. Families → attributes → attribute groups → options → channels/locales → completeness. The value nesting is attribute → channel → locale → value, which trips everyone up on day one. Model variants as product models + child products, not as separate families.
Extending the PIM itself (only when the API can't do it):
src/ (or a private vendor/), register in config/bundles.php, autoload via composer.json.EventDispatcher subscribers for pre/post-save product logic, and implement StepElementInterface / job steps for custom import/export behaviour.Job over hand-rolling a data loader — batch jobs give you retries, logs, and the UI for free.Upgrades are a project, not a composer update. Sequential minor upgrades only, run every migration in upgrades/, doctrine:migrations:migrate, pim:installer:db, then full reindex.
v2026.1 and v2026.2. Pin exact: "akeneo/pim-community-dev": "v2026.3". Never use ^.bin/console pim:product:index --all (or the "Update product index" job, or pim:product:index:daemon in prod). 90% of "the API returns stale data" bugs are this./api/rest/v1 is the legacy route; newer versions ship a second, OpenAPI-documented API. Check which one your build exposes before writing a client — endpoints, auth grants and response envelopes differ.POST /api/rest/v1/media-files (multipart or base64 JSON) → then set the attribute value to the returned code. Uploading a URL directly does not work.422 payloads carry errors[].property (e.g. values) and errors[].message. Log the whole body; the human-readable reason is in there.artisan. Logs in var/log/, bin/console cache:clear, APP_ENV=dev for the profiler. Your Laravel instincts (Eloquent, Blade, facades, config/) map conceptually only — it's Doctrine entities and Symfony DI here.akeneo:elasticsearch:reset-indexes) need to be planned; a 100K-SKU reindex is hours, not minutes.pim-community-dev for your project. Use pim-community-standard (or a project skeleton) + your own bundle, so upgrades stay merges rather than rewrites.How can I help you explore Laravel packages today?