CoolCMS API

JsonImportParser
in package
implements ImportParserInterface

FinalYes

JSON parser producing an {@see ImportDto} with the same output shape as {@see XmlImportParser}: an element maps to a property, repeatable elements to arrays, texts with `lang` to an object keyed by the language alias, a collection is either a plain array (default mode) or `{"mode": "...", "items": [...]}`. Tri-state: a missing key means untouched, `null` (or `""` for texts) means clear.

The whole file is decoded with json_decode() at once (20 MB limit, unlike XML, which streams because of its 100 MB limit), but the DTO still fills ImportDto::getProducts() with an iterator over the decoded array, so that validator and executor stay format independent.

Row numbers for the log: JSON has no rows, so ImportProductDto::$line, ImportVariantDto::$line and ImportBundleDto::$line carry the 1-based position of the item in its array (products[2] gives line = 3, a variant at variants[0] gives line = 1), not a global order and not a real file row. A log row always carries the code too, so two cards with the same variant position stay distinguishable.

Table of Contents

Interfaces

ImportParserInterface
Common interface of the three format parsers; all fill one `ImportDto`, so validator and executor are format-independent. {@see XmlImportParser}, {@see CsvImportParser} and {@see JsonImportParser} implement it; {@see ImportParserFactory} selects the implementation by `ProductImportFormat`.

Constants

BUNDLE_KEYS  : array<string|int, mixed> = ['code', 'id', 'action', 'name', 'longName', 's...
BUNDLE_SCALAR_KEYS  : array<string|int, mixed> = ['activated', 'vat']
BUNDLE_TEXT_KEYS  : array<string|int, mixed> = ['name', 'longName', 'shortDescription', 'descr...
MAX_BYTES  : int = 20 * 1024 * 1024
Size limit of CSV/JSON (20 MB); a defensive cap here too, because the admin add form checks it earlier.
PRODUCT_KEYS  : array<string|int, mixed> = ['id', 'action', 'name', 'description', 'produc...
PRODUCT_SCALAR_KEYS  : array<string|int, mixed> = ['producer', 'productType', 'activated']
PRODUCT_TEXT_KEYS  : array<string|int, mixed> = ['name', 'description']
ROOT_KEYS  : array<string|int, mixed> = ['version', 'settings', 'products', 'bundles']
SETTINGS_KEYS  : array<string|int, mixed> = ['mode', 'matchBy', 'defaultLang', 'collectionM...
VARIANT_KEYS  : array<string|int, mixed> = ['id', 'action', 'code', 'ean', 'isbn', 'name',...
VARIANT_SCALAR_KEYS  : array<string|int, mixed> = ['code', 'ean', 'isbn', 'weight', 'warranty', '...
VARIANT_TEXT_KEYS  : array<string|int, mixed> = ['name', 'longName', 'shortDescription', 'descr...

Methods

parse()  : ImportDto
buildAccessories()  : ImportCollectionDto<string|int, ImportAccessoryDto>|null
buildBundle()  : ImportBundleDto
buildCategories()  : ImportCollectionDto<string|int, ImportCategoryDto>|null
buildImages()  : ImportCollectionDto<string|int, ImportImageDto>|null
buildParameters()  : ImportCollectionDto<string|int, ImportParameterDto>|null
buildPrices()  : array<int, ImportPriceDto>
buildProduct()  : ImportProductDto
buildSettings()  : ImportSettingsDto
buildStock()  : ImportStockDto|null
buildTags()  : ImportCollectionDto<string|int, ImportTagDto>|null
buildVariant()  : ImportVariantDto
checkUnknownKeys()  : void
readActionKey()  : string|null
readCollectionShape()  : array{mode: ?string, items: list}|null
Recognizes the collection shape: a plain array is the default mode, `{"mode","items"}` is explicit, `null`/`[]` clears (`replace` with empty items; CSV has the same convention with `#NULL`).
readIntKey()  : int|null
A missing key (or `null`) returns `null`. A present but invalid `id` (negative, 0, decimal, `1e2`, bool, array, non-canonical string, overflow) is not "missing": it logs `KIND_MALFORMED` and returns `null`, and the item is then blocked. Policy: an `int` >= 1 or a canonical digit string ("12") is accepted.
readLangTexts()  : array<int, ImportValue>
Texts with `lang` as an object keyed by the language alias: `{"cs": "...", "en": "..."}`. The short form, a plain string or `null`, is shorthand for `defaultLang` (the job reads it the same way from `lang=null`, {@see ImportCodebooks::findLanguageId()}).
readNullableString()  : string|null
readOptionalScalarValue()  : ImportValue|null
readScalarValue()  : ImportValue|null
Tri-state reader: `null`/`""` clears, otherwise the value (bool/number to string).
yieldProducts()  : Generator

Constants

BUNDLE_KEYS

private array<string|int, mixed> BUNDLE_KEYS = ['code', 'id', 'action', 'name', 'longName', 'shortDescription', 'description', 'activated', 'vat', 'tags', 'prices', 'images', 'items']

BUNDLE_SCALAR_KEYS

private array<string|int, mixed> BUNDLE_SCALAR_KEYS = ['activated', 'vat']

BUNDLE_TEXT_KEYS

private array<string|int, mixed> BUNDLE_TEXT_KEYS = ['name', 'longName', 'shortDescription', 'description']

MAX_BYTES

Size limit of CSV/JSON (20 MB); a defensive cap here too, because the admin add form checks it earlier.

private int MAX_BYTES = 20 * 1024 * 1024

PRODUCT_KEYS

private array<string|int, mixed> PRODUCT_KEYS = ['id', 'action', 'name', 'description', 'producer', 'productType', 'activated', 'image', 'categories', 'variants']

PRODUCT_SCALAR_KEYS

private array<string|int, mixed> PRODUCT_SCALAR_KEYS = ['producer', 'productType', 'activated']

PRODUCT_TEXT_KEYS

private array<string|int, mixed> PRODUCT_TEXT_KEYS = ['name', 'description']

ROOT_KEYS

private array<string|int, mixed> ROOT_KEYS = ['version', 'settings', 'products', 'bundles']

allowed keys of the root object.

SETTINGS_KEYS

private array<string|int, mixed> SETTINGS_KEYS = ['mode', 'matchBy', 'defaultLang', 'collectionMode', 'autoCreateProducers', 'autoCreateOptions', 'autoCreateCategories', 'stopOnError']

same set as XmlImportParser::SETTINGS_TAGS.

VARIANT_KEYS

private array<string|int, mixed> VARIANT_KEYS = ['id', 'action', 'code', 'ean', 'isbn', 'name', 'longName', 'shortDescription', 'description', 'unit', 'weight', 'warranty', 'freeDelivery', 'freePayment', 'publishTime', 'unpublishTime', 'activated', 'vat', 'state', 'tags', 'parameters', 'prices', 'stock', 'images', 'accessories']

VARIANT_SCALAR_KEYS

private array<string|int, mixed> VARIANT_SCALAR_KEYS = ['code', 'ean', 'isbn', 'weight', 'warranty', 'freeDelivery', 'freePayment', 'publishTime', 'unpublishTime', 'activated', 'vat', 'state']

VARIANT_TEXT_KEYS

private array<string|int, mixed> VARIANT_TEXT_KEYS = ['name', 'longName', 'shortDescription', 'description']

Methods

parse()

public parse(string $absolutePath[, string|null $schemaPath = null ]) : ImportDto
Parameters
$absolutePath : string

absolute path to the file (never from the request, always the job filePath)

$schemaPath : string|null = null

optional xsd shape check; only XML supports it, csv/json ignore the parameter

Return values
ImportDto

checkUnknownKeys()

private checkUnknownKeys(array<string|int, mixed> $raw, array<int, string> $allowed, string $context, int $line, array<int, ImportStructureIssueDto> &$issues) : void
Parameters
$raw : array<string|int, mixed>
$allowed : array<int, string>
$context : string
$line : int
$issues : array<int, ImportStructureIssueDto>

readActionKey()

private readActionKey(array<string|int, mixed> $raw) : string|null
Parameters
$raw : array<string|int, mixed>
Return values
string|null

readCollectionShape()

Recognizes the collection shape: a plain array is the default mode, `{"mode","items"}` is explicit, `null`/`[]` clears (`replace` with empty items; CSV has the same convention with `#NULL`).

private readCollectionShape(mixed $raw, int $line, string $context, array<int, ImportStructureIssueDto> &$issues) : array{mode: ?string, items: list}|null
Parameters
$raw : mixed
$line : int
$context : string
$issues : array<int, ImportStructureIssueDto>
Return values
array{mode: ?string, items: list}|null —

null when the tag was in the file but has no valid shape (the defect is logged and the section is skipped as if it were missing)

readIntKey()

A missing key (or `null`) returns `null`. A present but invalid `id` (negative, 0, decimal, `1e2`, bool, array, non-canonical string, overflow) is not "missing": it logs `KIND_MALFORMED` and returns `null`, and the item is then blocked. Policy: an `int` >= 1 or a canonical digit string ("12") is accepted.

private readIntKey(array<string|int, mixed> $raw, string $key, int $line, array<int, ImportStructureIssueDto> &$issues, string $context) : int|null
Parameters
$raw : array<string|int, mixed>
$key : string
$line : int
$issues : array<int, ImportStructureIssueDto>
$context : string
Return values
int|null

readLangTexts()

Texts with `lang` as an object keyed by the language alias: `{"cs": "...", "en": "..."}`. The short form, a plain string or `null`, is shorthand for `defaultLang` (the job reads it the same way from `lang=null`, {@see ImportCodebooks::findLanguageId()}).

private readLangTexts(mixed $raw, int $line, string $context, array<int, ImportStructureIssueDto> &$issues) : array<int, ImportValue>
Parameters
$raw : mixed
$line : int
$context : string
$issues : array<int, ImportStructureIssueDto>
Return values
array<int, ImportValue>

readNullableString()

private readNullableString(array<string|int, mixed> $raw, string $key) : string|null
Parameters
$raw : array<string|int, mixed>
$key : string
Return values
string|null

readScalarValue()

Tri-state reader: `null`/`""` clears, otherwise the value (bool/number to string).

private readScalarValue(mixed $raw, int $line, string $context, array<int, ImportStructureIssueDto> &$issues) : ImportValue|null

IMPORTANT: an object or array in place of a scalar field is a shape error, not a "clear" instruction. If an empty ImportValue were returned, {"ean": }} would pass without an error and the writer would delete the EAN of an otherwise valid update (setEan($nullOut ? null : $raw)). Four states must stay distinct: field missing (do not touch), null/"" (clear), value (write), wrong type (reject the item).

Parameters
$raw : mixed
$line : int
$context : string
$issues : array<int, ImportStructureIssueDto>
Return values
ImportValue|null —

null for a wrong type: the field is not written and the issue blocks the item

On this page

Search results