1. Go to this page and download the library: Download maikschneider/tca-api library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
final class ArticleCallbacks
{
public function buildLabel(array $serializedRow, array $rawRow): string
{
// $serializedRow already contains the resolved 'color_id' relation.
$color = $serializedRow['color_id']['name'] ?? 'n/a';
return sprintf('%s (%s)', $serializedRow['title'] ?? '', $color);
}
}
use MaikSchneider\TcaApi\Filter\ExactFilter;
use MaikSchneider\TcaApi\Filter\MmFilter;
use MaikSchneider\TcaApi\Filter\PartialFilter;
use MaikSchneider\TcaApi\Filter\RangeFilter;
use MaikSchneider\TcaApi\Filter\SearchFilter;
use MaikSchneider\TcaApi\Filter\WordStartFilter;
'filters' => [
'title' => ExactFilter::class, // ?title=Foo (or legacy ?filters[title]=Foo)
'name' => PartialFilter::class, // ?name=oo → LIKE %oo%
'slug' => WordStartFilter::class, // ?slug=Fo → LIKE Fo%
'year' => RangeFilter::class, // ?filters[year][gte]=2020&filters[year][lte]=2024
'q' => [ // Full-text search — options form
SearchFilter::class,
[
'columns' => ['title', 'teaser', 'body'],
'match' => 'partial', // 'partial' (default) or 'word_start'
],
],
// Shorthand: derive MM config from TCA automatically
'categories' => MmFilter::class,
// Options form: supply MM table config explicitly
'tags' => [
MmFilter::class,
[
'mm_table' => 'tx_myext_article_tag_mm',
'mm_local_key' => 'uid_local',
'mm_foreign_key' => 'uid_foreign',
],
],
],
'filters' => [
// Overrideable default — applied when ?color_id is absent
'color_id' => [ExactFilter::class, ['default' => '1']],
// Private filter — default always applies, cannot be overridden via URL,
// and does not appear in the OpenAPI spec
'deleted' => [ExactFilter::class, ['default' => '0', 'private' => true]],
],
'order' => [
'allowed' => ['title', 'uid'], // Columns allowed in ?order[column]=asc|desc
'default' => ['uid' => 'asc'], // Fallback when no order is requested
],
use MaikSchneider\TcaApi\Enum\AccessRole;
'security' => [
// list and show are PUBLIC by default — only specify to restrict them
'create' => AccessRole::FE_USER, // Requires a logged-in frontend user
'update' => AccessRole::OWNER, // Only the record owner may update
'delete' => AccessRole::OWNER,
],
use MaikSchneider\TcaApi\Enum\AccessRole;
'security' => [
'create' => AccessRole::FE_USER,
'update' => AccessRole::OWNER,
'delete' => AccessRole::OWNER,
],
'ownership' => [
'column' => 'fe_user_id', // DB column holding the owner's FE user UID
],
'ownership' => [
'column' => 'fe_user_id', // column checked on update/delete (also written on create)
'setOnCreate' => 'fe_creator_id', // additional column written on create only
],
use MaikSchneider\TcaApi\OperationHandler\OperationHandlerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
interface OperationHandlerInterface
{
public function supports(ServerRequestInterface $request, string $operation, array $config): bool;
public function handle(ServerRequestInterface $request, array $config): ResponseInterface;
public function getPriority(): int;
}
use MaikSchneider\TcaApi\OperationHandler\OperationHandlerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
#[Autoconfigure(public: true)]
class PublishHandler implements OperationHandlerInterface
{
public function supports(ServerRequestInterface $request, string $operation, array $config): bool
{
return $operation === 'publish'
&& ($config['general']['table'] ?? '') === 'tx_myext_domain_model_article';
}
public function handle(ServerRequestInterface $request, array $config): ResponseInterface
{
$uid = (int)$request->getAttribute('tca_api.uid');
// … publish logic …
}
public function getPriority(): int
{
return 10;
}
}
use MaikSchneider\TcaApi\Registry\HandlerRegistry;
use My\Extension\OperationHandler\PublishHandler;
// New operation type — priority 10 (default)
HandlerRegistry::register(PublishHandler::class);
// Override a built-in handler — checked before the built-in (priority 20 > 10)
HandlerRegistry::register(MyCustomShowHandler::class, priority: 20);
use MaikSchneider\TcaApi\Filter\FilterContext;
use MaikSchneider\TcaApi\Filter\FilterInterface;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
final class PublishedAfterFilter implements FilterInterface
{
public function apply(QueryBuilder $qb, FilterContext $context): void
{
$qb->andWhere($qb->expr()->gte(
$context->column,
$qb->createNamedParameter((int)$context->value),
));
}
}
use My\Extension\Filter\PublishedAfterFilter;
'filters' => [
'publish_date' => PublishedAfterFilter::class,
],
'filters' => [
'publish_date' => [
PublishedAfterFilter::class,
['threshold' => 30], // available via $context->option('threshold')
],
],
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.