Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct php type for fields with TCA type json?

Tags:

php

typo3

extbase

I want to store some options in the DB like this:

    'question_options' => [
        'exclude' => false,
        'label' => 'xxx',
        'description' => 'xxx',
        'config' => [
            'type' => 'json',
            'default' => ''
        ],
    ],

What would the correct type for my Model.php be?

/**
 * questionOptions
 *
 * @var string ?? array ?? object ?? mixed ??
 */
protected $questionOptions;

Array shows null and string gets escaped when setting it through a setter.

like image 395
Doku Avatar asked Oct 29 '25 00:10

Doku


1 Answers

You could make use of TYPO3's TypeInterface which will get raw data passed as constructor argument by the DataMapper. This works similar for the PropertyMapper which does this via the CoreTypeConverter.

This allows you to use classes which implement the TypeInterface as type for domain model properties. In this particular case you can automatically convert the raw JSON string to an array-like structure like this:

<?php

declare(strict_types=1);

namespace Acme\Package\Domain\Data;

use TYPO3\CMS\Core\Type\TypeInterface;

final class JsonData extends \ArrayObject implements TypeInterface
{
    public function __construct(string $jsonString)
    {
        $data = json_decode(
            json: $jsonString,
            associative: true,
            flags: \JSON_THROW_ON_ERROR,
        );

        parent::__construct($data);
    }

    public function __toString(): string
    {
        return json_encode(
            value: $this,
            flags: \JSON_THROW_ON_ERROR,
        );
    }
}

Your domain model can now use this as property type:


declare(strict_types=1);

namespace Acme\Package\Domain\Model;

use Acme\Package\Domain\Data\JsonData;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;

final class Example extends AbstractEntity
{
    public ?JsonData $data = null;
}

Now all instances allow you to transparently access the already decoded JSON data. Assuming an object $example1 of this Example model which has {"foo":"bar"} as data in its tx_package_domain_model_example.data column:

$example1->data['foo'];
{example1.data.foo}

You can see a real-life implementation of this in the pagemachine/typo3-formlog package:

  1. Domain/Data/JsonData.php
  2. Domain/Model/FormLogEntry.php
like image 63
Mathias Brodala Avatar answered Oct 31 '25 13:10

Mathias Brodala