Try Live
Add Docs
Rankings
Pricing
Docs
Install
Install
Docs
Pricing
More...
More...
Try Live
Rankings
Enterprise
Create API Key
Add Docs
TYPO3
https://github.com/typo3/typo3
Admin
The TYPO3 Core - Enterprise Content Management System. Synchronized mirror of
...
Tokens:
1,874,017
Snippets:
15,757
Trust Score:
7.5
Update:
6 days ago
Context
Skills
Chat
Benchmark
83.5
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# TYPO3 CMS Core TYPO3 CMS is a free and open-source enterprise Content Management System written in PHP. It provides a flexible framework for building websites and web applications with comprehensive backend administration, extensible plugin architecture via Extbase/Fluid, and robust content management capabilities. The core is built on modern PHP standards (PHP 8.2+), uses Doctrine DBAL for database abstraction, Symfony components for routing/mail/console, and follows PSR standards for HTTP messaging and dependency injection. TYPO3's architecture separates concerns into system extensions (sysext) providing core functionality: `core` for database/cache/authentication APIs, `extbase` for MVC framework, `fluid` for templating, `backend` for administration interface, and `frontend` for page rendering. Extensions follow strict naming conventions and can be configured via TCA (Table Configuration Array), TypoScript, and YAML-based site configuration. ## Database API - ConnectionPool The ConnectionPool provides database connections using Doctrine DBAL with automatic table-to-connection mapping and query restrictions for soft-delete, workspaces, and language handling. ```php <?php use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Utility\GeneralUtility; // Get connection pool instance $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class); // Get connection for a specific table (honors table mapping) $connection = $connectionPool->getConnectionForTable('pages'); // Simple insert $connection->insert( 'pages', [ 'title' => 'New Page', 'pid' => 1, 'doktype' => 1, 'crdate' => time(), 'tstamp' => time() ] ); $newUid = (int)$connection->lastInsertId(); // Simple update $connection->update( 'pages', ['title' => 'Updated Title', 'tstamp' => time()], ['uid' => $newUid] ); // Simple delete $connection->delete('pages', ['uid' => $newUid]); // Direct query execution $result = $connection->executeQuery( 'SELECT * FROM pages WHERE pid = :pid', ['pid' => 1], ['pid' => \Doctrine\DBAL\ParameterType::INTEGER] ); $rows = $result->fetchAllAssociative(); ``` ## Database API - QueryBuilder The QueryBuilder provides an object-oriented interface for building SQL queries with automatic identifier quoting, parameter binding, and built-in query restrictions for deleted records, workspaces, and more. ```php <?php use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; use TYPO3\CMS\Core\Utility\GeneralUtility; $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable('tt_content'); // SELECT query with conditions $result = $queryBuilder ->select('uid', 'header', 'bodytext', 'pid') ->from('tt_content') ->where( $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter(1, \Doctrine\DBAL\ParameterType::INTEGER)), $queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('text')) ) ->orderBy('sorting', 'ASC') ->setMaxResults(10) ->executeQuery(); $records = $result->fetchAllAssociative(); // JOIN query example $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable('tt_content'); $result = $queryBuilder ->select('c.uid', 'c.header', 'p.title AS page_title') ->from('tt_content', 'c') ->leftJoin('c', 'pages', 'p', $queryBuilder->expr()->eq('c.pid', $queryBuilder->quoteIdentifier('p.uid'))) ->where( $queryBuilder->expr()->like('c.header', $queryBuilder->createNamedParameter('%search%')) ) ->executeQuery(); // COUNT query $count = $queryBuilder ->count('uid') ->from('pages') ->where($queryBuilder->expr()->eq('doktype', $queryBuilder->createNamedParameter(1))) ->executeQuery() ->fetchOne(); // Remove default restrictions (e.g., to include deleted records) $queryBuilder->getRestrictions()->removeAll(); $queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(DeletedRestriction::class)); // IN clause with array parameters $uids = [1, 2, 3, 4, 5]; $queryBuilder ->select('*') ->from('pages') ->where( $queryBuilder->expr()->in( 'uid', $queryBuilder->createNamedParameter($uids, \Doctrine\DBAL\ArrayParameterType::INTEGER) ) ) ->executeQuery(); ``` ## Cache API - CacheManager The CacheManager provides a unified caching system supporting multiple backends (database, file, Redis, APCu, Memcached) with tag-based cache invalidation. ```php <?php use TYPO3\CMS\Core\Cache\CacheManager; use TYPO3\CMS\Core\Utility\GeneralUtility; $cacheManager = GeneralUtility::makeInstance(CacheManager::class); // Get a specific cache $cache = $cacheManager->getCache('my_extension_cache'); // Set cache entry with tags and lifetime (seconds) $cache->set( 'my_cache_identifier', ['data' => 'Some cached data', 'timestamp' => time()], ['tag_page_1', 'tag_content'], 3600 // 1 hour lifetime ); // Get cache entry if ($cache->has('my_cache_identifier')) { $data = $cache->get('my_cache_identifier'); } // Flush by tag $cache->flushByTag('tag_page_1'); // Flush by multiple tags $cache->flushByTags(['tag_page_1', 'tag_content']); // Flush entire cache $cache->flush(); // Flush all caches in a group $cacheManager->flushCachesInGroup('pages'); $cacheManager->flushCachesInGroupByTag('pages', 'pageId_42'); // Cache configuration in ext_localconf.php // $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['my_extension_cache'] = [ // 'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class, // 'backend' => \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, // 'options' => [], // 'groups' => ['pages'] // ]; ``` ## Extbase - ActionController The ActionController is the base class for MVC controllers in Extbase, providing action dispatching, argument validation, view rendering, and flash messages. ```php <?php namespace MyVendor\MyExtension\Controller; use Psr\Http\Message\ResponseInterface; use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; use TYPO3\CMS\Extbase\Annotation as Extbase; use MyVendor\MyExtension\Domain\Repository\BlogRepository; use MyVendor\MyExtension\Domain\Model\Blog; class BlogController extends ActionController { public function __construct( protected readonly BlogRepository $blogRepository ) {} public function listAction(): ResponseInterface { $blogs = $this->blogRepository->findAll(); $this->view->assign('blogs', $blogs); return $this->htmlResponse(); } public function showAction(Blog $blog): ResponseInterface { $this->view->assign('blog', $blog); return $this->htmlResponse(); } public function newAction(): ResponseInterface { $this->view->assign('newBlog', new Blog()); return $this->htmlResponse(); } #[Extbase\IgnoreValidation(['value' => 'newBlog'])] public function createAction(Blog $newBlog): ResponseInterface { $this->blogRepository->add($newBlog); $this->addFlashMessage( 'Blog was created successfully.', 'Success', ContextualFeedbackSeverity::OK ); return $this->redirect('list'); } public function editAction(Blog $blog): ResponseInterface { $this->view->assign('blog', $blog); return $this->htmlResponse(); } public function updateAction(Blog $blog): ResponseInterface { $this->blogRepository->update($blog); $this->addFlashMessage('Blog was updated.', 'Updated'); return $this->redirect('list'); } public function deleteAction(Blog $blog): ResponseInterface { $this->blogRepository->remove($blog); $this->addFlashMessage('Blog was deleted.', 'Deleted', ContextualFeedbackSeverity::WARNING); return $this->redirect('list'); } // Return JSON response public function apiAction(): ResponseInterface { $data = ['status' => 'ok', 'items' => []]; return $this->jsonResponse(json_encode($data)); } // Forward to another action protected function forwardToOtherAction(): ResponseInterface { return $this->forward('show', 'Blog', null, ['blog' => $blog]); } // Redirect to external URI protected function redirectExternal(): ResponseInterface { return $this->redirectToUri('https://example.com', 0, 301); } } ``` ## Extbase - Repository The Repository base class provides data access methods for domain objects with automatic query settings, orderings, and cache tagging. ```php <?php namespace MyVendor\MyExtension\Domain\Repository; use TYPO3\CMS\Extbase\Persistence\Repository; use TYPO3\CMS\Extbase\Persistence\QueryInterface; use TYPO3\CMS\Extbase\Persistence\QueryResultInterface; use MyVendor\MyExtension\Domain\Model\Blog; /** * @extends Repository<Blog> */ class BlogRepository extends Repository { // Default orderings protected $defaultOrderings = [ 'crdate' => QueryInterface::ORDER_DESCENDING, 'title' => QueryInterface::ORDER_ASCENDING ]; // Find by single property public function findByCategory(int $categoryUid): QueryResultInterface { $query = $this->createQuery(); $query->matching( $query->equals('category', $categoryUid) ); return $query->execute(); } // Complex query with multiple conditions public function findPublishedByAuthor(int $authorUid, int $limit = 10): QueryResultInterface { $query = $this->createQuery(); $query->matching( $query->logicalAnd( $query->equals('author', $authorUid), $query->equals('published', true), $query->lessThanOrEqual('publishDate', new \DateTime()) ) ); $query->setOrderings(['publishDate' => QueryInterface::ORDER_DESCENDING]); $query->setLimit($limit); return $query->execute(); } // Full-text search with LIKE public function searchByTitle(string $searchTerm): QueryResultInterface { $query = $this->createQuery(); $query->matching( $query->like('title', '%' . $searchTerm . '%') ); return $query->execute(); } // Using findBy and findOneBy (Doctrine-style) public function findActiveBlogs(): QueryResultInterface { return $this->findBy(['active' => true], ['title' => QueryInterface::ORDER_ASCENDING]); } public function findOneBySlug(string $slug): ?Blog { return $this->findOneBy(['slug' => $slug]); } // Override query settings to include hidden records public function findAllIncludingHidden(): QueryResultInterface { $query = $this->createQuery(); $query->getQuerySettings()->setIgnoreEnableFields(true); return $query->execute(); } // Include records from all storage pages public function findAllGlobally(): QueryResultInterface { $query = $this->createQuery(); $query->getQuerySettings()->setRespectStoragePage(false); return $query->execute(); } // Raw SQL via statement (use sparingly) public function findByCustomQuery(int $minPosts): array { $query = $this->createQuery(); $query->statement( 'SELECT * FROM tx_myext_domain_model_blog WHERE post_count >= ? ORDER BY title', [$minPosts] ); return $query->execute()->toArray(); } } ``` ## Fluid Templates - Form ViewHelper The FormViewHelper generates HTML forms with CSRF protection, argument prefixing, and validation integration for Extbase controllers. ```html <!-- Basic form with object binding --> <f:form action="create" controller="Blog" object="{blog}" name="blog" method="post"> <f:form.textfield property="title" placeholder="Enter title" /> <f:form.textarea property="description" rows="5" cols="40" /> <f:form.hidden property="category" value="{category.uid}" /> <f:form.checkbox property="published" value="1" /> <f:form.submit value="Save" /> </f:form> <!-- Form with file upload --> <f:form action="upload" enctype="multipart/form-data"> <f:form.upload property="file" /> <f:form.submit value="Upload" /> </f:form> <!-- Select dropdown with options --> <f:form action="filter" method="get"> <f:form.select property="category" options="{categories}" optionValueField="uid" optionLabelField="title" prependOptionLabel="All categories" /> </f:form> <!-- Radio buttons --> <f:form action="save"> <f:for each="{options}" as="option"> <label> <f:form.radio property="selectedOption" value="{option.uid}" /> {option.title} </label> </f:for> </f:form> <!-- Country select with built-in country data --> <f:form.countrySelect property="country" sortByOptionLabel="true" prioritizedCountries="{0: 'DE', 1: 'AT', 2: 'CH'}" /> <!-- Validation errors --> <f:form.validationResults for="blog"> <f:if condition="{validationResults.flattenedErrors}"> <ul class="errors"> <f:for each="{validationResults.flattenedErrors}" as="errors" key="propertyPath"> <li>{propertyPath}: <f:for each="{errors}" as="error">{error.message}</f:for></li> </f:for> </ul> </f:if> </f:form.validationResults> ``` ## Fluid Templates - Link and URI ViewHelpers ViewHelpers for generating links to Extbase actions, pages, files, and external URLs with proper URL encoding and routing. ```html <!-- Link to Extbase action --> <f:link.action action="show" controller="Blog" arguments="{blog: blog}"> View Blog </f:link.action> <!-- Link with plugin and extension name --> <f:link.action action="list" controller="Blog" extensionName="MyExtension" pluginName="BlogList" pageUid="42"> All Blogs </f:link.action> <!-- URI only (for JavaScript or attributes) --> <a href="{f:uri.action(action: 'show', arguments: '{blog: blog}')}">View</a> <!-- Link to page --> <f:link.page pageUid="42" additionalParams="{foo: 'bar'}">Go to page</f:link.page> <!-- Typolink (using TypoLink syntax) --> <f:link.typolink parameter="42">Page Link</f:link.typolink> <f:link.typolink parameter="t3://page?uid=42&type=0">Typed Link</f:link.typolink> <f:link.typolink parameter="t3://file?uid=15">File Link</f:link.typolink> <!-- External link --> <f:link.external uri="https://typo3.org" target="_blank" rel="noopener">TYPO3</f:link.external> <!-- Email link --> <f:link.email email="info@example.com">Contact Us</f:link.email> <!-- File link --> <f:link.file file="{fileReference}" download="true">Download File</f:link.file> <!-- Image with URI --> <f:image image="{fileReference}" width="800c" height="600c" alt="{image.alternative}" /> <f:uri.image image="{fileReference}" maxWidth="1200" /> <!-- Resource URI (for extension assets) --> <link rel="stylesheet" href="{f:uri.resource(path: 'Css/styles.css', extensionName: 'MyExtension')}" /> <script src="{f:uri.resource(path: 'JavaScript/app.js')}"></script> ``` ## Fluid Templates - Format and Render ViewHelpers ViewHelpers for formatting data, rendering content, and controlling output. ```html <!-- Date formatting --> <f:format.date format="d.m.Y H:i">{blog.crdate}</f:format.date> <f:format.date date="now" format="Y-m-d" /> <!-- Currency formatting --> <f:format.currency currencySign="EUR" decimalSeparator="," thousandsSeparator=".">1234.56</f:format.currency> <!-- Number formatting --> <f:format.number decimals="2" decimalSeparator="." thousandsSeparator=",">{price}</f:format.number> <!-- Bytes formatting --> <f:format.bytes decimals="2">{fileSize}</f:format.bytes> <!-- String cropping --> <f:format.crop maxCharacters="100" append="...">{blog.description}</f:format.crop> <!-- HTML processing --> <f:format.html>{bodytext}</f:format.html> <f:format.raw>{trustedHtml}</f:format.raw> <f:sanitize.html>{untrustedHtml}</f:sanitize.html> <!-- HTML entities --> <f:format.htmlentities>{userInput}</f:format.htmlentities> <f:format.htmlentitiesDecode>{encodedString}</f:format.htmlentitiesDecode> <!-- Padding --> <f:format.padding padLength="10" padString="0">{orderNumber}</f:format.padding> <!-- Translation --> <f:translate key="LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:label.title" /> <f:translate key="label.greeting" arguments="{0: username}" /> <!-- Render partial --> <f:render partial="BlogItem" arguments="{blog: blog}" /> <!-- Render section --> <f:render section="MainContent" arguments="{_all}" /> <!-- Render with optional section --> <f:render section="OptionalSection" optional="true" /> <!-- Flash messages --> <f:flashMessages queueIdentifier="extbase.flashmessages.tx_myext_plugin" /> <!-- Debug output --> <f:debug>{complexObject}</f:debug> <f:debug inline="true" maxDepth="3">{data}</f:debug> <!-- CObject rendering (TypoScript) --> <f:cObject typoscriptObjectPath="lib.myObject" data="{record}" /> <!-- Render tt_content record --> <f:render.record record="{contentRecord}" /> ``` ## DataHandler API The DataHandler (formerly TCEmain) processes all record operations in TYPO3 backend - create, update, delete, copy, move, and localize records with proper permission checks and hook execution. ```php <?php use TYPO3\CMS\Core\DataHandling\DataHandler; use TYPO3\CMS\Core\Utility\GeneralUtility; $dataHandler = GeneralUtility::makeInstance(DataHandler::class); // Create new record $data = [ 'pages' => [ 'NEW1234' => [ 'pid' => 1, // Parent page ID 'title' => 'New Page Title', 'doktype' => 1, 'hidden' => 0 ] ] ]; $dataHandler->start($data, []); $dataHandler->process_datamap(); $newPageUid = $dataHandler->substNEWwithIDs['NEW1234']; // Update existing record $data = [ 'pages' => [ 42 => [ 'title' => 'Updated Title', 'subtitle' => 'New subtitle' ] ] ]; $dataHandler->start($data, []); $dataHandler->process_datamap(); // Delete record $cmd = [ 'pages' => [ 42 => [ 'delete' => 1 ] ] ]; $dataHandler->start([], $cmd); $dataHandler->process_cmdmap(); // Copy record $cmd = [ 'tt_content' => [ 10 => [ 'copy' => 42 // Copy to page 42 ] ] ]; $dataHandler->start([], $cmd); $dataHandler->process_cmdmap(); $copiedUid = $dataHandler->copyMappingArray['tt_content'][10]; // Move record $cmd = [ 'tt_content' => [ 10 => [ 'move' => 42 // Move to page 42 ] ] ]; $dataHandler->start([], $cmd); $dataHandler->process_cmdmap(); // Localize record (create translation) $cmd = [ 'tt_content' => [ 10 => [ 'localize' => 1 // Translate to language 1 ] ] ]; $dataHandler->start([], $cmd); $dataHandler->process_cmdmap(); // Check for errors if ($dataHandler->errorLog) { foreach ($dataHandler->errorLog as $error) { // Handle error } } ``` ## Site Configuration and Routing The SiteFinder and PageRouter provide site resolution and URL routing based on YAML site configurations. ```php <?php use TYPO3\CMS\Core\Site\SiteFinder; use TYPO3\CMS\Core\Routing\PageRouter; use TYPO3\CMS\Core\Utility\GeneralUtility; $siteFinder = GeneralUtility::makeInstance(SiteFinder::class); // Get all configured sites $sites = $siteFinder->getAllSites(); // Get site by identifier $site = $siteFinder->getSiteByIdentifier('main'); // Get site by root page ID $site = $siteFinder->getSiteByRootPageId(1); // Get site by any page ID (traverses rootline) $site = $siteFinder->getSiteByPageId(42); // Site properties $baseUrl = $site->getBase(); // UriInterface $rootPageId = $site->getRootPageId(); $languages = $site->getLanguages(); $defaultLanguage = $site->getDefaultLanguage(); // Get specific language $germanLanguage = $site->getLanguageById(1); $languageBase = $germanLanguage->getBase(); $languageTitle = $germanLanguage->getTitle(); $locale = $germanLanguage->getLocale(); // Generate URL for a page $pageRouter = GeneralUtility::makeInstance(PageRouter::class, $site); $uri = $pageRouter->generateUri( 42, // Page UID ['_language' => $germanLanguage, 'foo' => 'bar'] ); // Site configuration (config/sites/main/config.yaml) /* rootPageId: 1 base: 'https://example.com/' languages: - title: English enabled: true languageId: 0 base: / locale: en_US.UTF-8 navigationTitle: EN flag: en-us-gb - title: German enabled: true languageId: 1 base: /de/ locale: de_DE.UTF-8 navigationTitle: DE flag: de fallbackType: strict routes: - route: robots.txt type: staticText content: "User-agent: *\nDisallow: /typo3/" errorHandling: - errorCode: 404 errorHandler: Page errorContentSource: 't3://page?uid=123' */ ``` ## Mail API The Mailer provides email sending capabilities using Symfony Mailer with support for multiple transports (SMTP, sendmail, etc.). ```php <?php use TYPO3\CMS\Core\Mail\MailMessage; use TYPO3\CMS\Core\Mail\FluidEmail; use TYPO3\CMS\Core\Utility\GeneralUtility; // Simple mail message $mail = GeneralUtility::makeInstance(MailMessage::class); $mail ->from('sender@example.com') ->to('recipient@example.com') ->subject('Subject Line') ->text('Plain text content') ->html('<h1>HTML Content</h1><p>Message body</p>') ->send(); // With multiple recipients $mail = GeneralUtility::makeInstance(MailMessage::class); $mail ->from('noreply@example.com') ->to('user1@example.com', 'user2@example.com') ->cc('cc@example.com') ->bcc('bcc@example.com') ->replyTo('reply@example.com') ->subject('Newsletter') ->html($htmlContent) ->send(); // With attachments $mail = GeneralUtility::makeInstance(MailMessage::class); $mail ->from('sender@example.com') ->to('recipient@example.com') ->subject('With Attachment') ->text('Please find attached document.') ->attachFromPath('/path/to/document.pdf', 'Document.pdf', 'application/pdf') ->attach($fileContent, 'data.csv', 'text/csv') ->send(); // FluidEmail with Fluid template $email = GeneralUtility::makeInstance(FluidEmail::class); $email ->to('recipient@example.com') ->from('noreply@example.com') ->subject('Welcome!') ->format(FluidEmail::FORMAT_BOTH) // HTML and plain text ->setTemplate('WelcomeEmail') ->assignMultiple([ 'username' => 'John Doe', 'activationLink' => 'https://example.com/activate/token123' ]); $mailer = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\Mailer::class); $mailer->send($email); // Template location: EXT:my_extension/Resources/Private/Templates/Email/WelcomeEmail.html ``` ## Event Listeners (PSR-14 Events) TYPO3 uses PSR-14 events for extensibility, replacing older hook mechanisms. Events are dispatched throughout the core and can be listened to via service configuration. ```php <?php // Event Listener Class namespace MyVendor\MyExtension\EventListener; use TYPO3\CMS\Core\Attribute\AsEventListener; use TYPO3\CMS\Core\DataHandling\Event\AfterRecordPublishedEvent; use TYPO3\CMS\Core\Mail\Event\AfterMailerSentMessageEvent; use TYPO3\CMS\Frontend\Event\ModifyPageLinkConfigurationEvent; #[AsEventListener] final class MyEventListener { #[AsEventListener] public function afterMailSent(AfterMailerSentMessageEvent $event): void { $sentMessage = $event->getSentMessage(); // Log sent message, update statistics, etc. } #[AsEventListener(identifier: 'my-record-published-listener')] public function afterRecordPublished(AfterRecordPublishedEvent $event): void { $tableName = $event->getTable(); $recordUid = $event->getRecordUid(); // Clear external cache, trigger webhook, etc. } #[AsEventListener] public function modifyPageLinkConfiguration(ModifyPageLinkConfigurationEvent $event): void { $configuration = $event->getConfiguration(); $configuration['additionalParams'] .= '&tracking=1'; $event->setConfiguration($configuration); } } // Services.yaml configuration (alternative to attributes) /* services: MyVendor\MyExtension\EventListener\MyEventListener: tags: - name: event.listener identifier: 'my-mail-listener' event: TYPO3\CMS\Core\Mail\Event\AfterMailerSentMessageEvent */ // Dispatching custom events namespace MyVendor\MyExtension\Event; final class BlogCreatedEvent { public function __construct( private readonly int $blogUid, private readonly array $blogData ) {} public function getBlogUid(): int { return $this->blogUid; } public function getBlogData(): array { return $this->blogData; } } // In your code use Psr\EventDispatcher\EventDispatcherInterface; class BlogService { public function __construct( private readonly EventDispatcherInterface $eventDispatcher ) {} public function createBlog(array $data): int { // ... create blog ... $event = new BlogCreatedEvent($blogUid, $data); $this->eventDispatcher->dispatch($event); return $blogUid; } } ``` ## GeneralUtility The GeneralUtility class provides static helper methods for common operations including object instantiation, string manipulation, file operations, and environment information. ```php <?php use TYPO3\CMS\Core\Utility\GeneralUtility; // Object instantiation (with dependency injection) $myService = GeneralUtility::makeInstance(MyService::class); // String operations $parts = GeneralUtility::trimExplode(',', 'a, b, c, ', true); // ['a', 'b', 'c'] $ints = GeneralUtility::intExplode(',', '1, 2, 3'); // [1, 2, 3] $truncated = GeneralUtility::fixed_lgd_cs('Long string here', 10); // 'Long st...' // Array operations $merged = GeneralUtility::mergeRecursiveWithOverrule($original, $override); // File operations $content = GeneralUtility::getUrl('https://example.com/api'); // HTTP GET $content = GeneralUtility::getUrl('/path/to/file.txt'); // File read GeneralUtility::writeFile('/path/to/file.txt', $content); $files = GeneralUtility::getFilesInDir('/path/to/dir/', 'php,txt'); GeneralUtility::mkdir_deep('/path/to/create/directories/'); // Path operations $relativePath = GeneralUtility::getFileAbsFileName('EXT:my_extension/Resources/Private/file.txt'); $isAbsolute = GeneralUtility::isAbsPath('/var/www/html'); // IP and environment $remoteIp = GeneralUtility::getIndpEnv('REMOTE_ADDR'); $hostName = GeneralUtility::getIndpEnv('HTTP_HOST'); $isMatch = GeneralUtility::cmpIP($remoteIp, '192.168.0.0/24,10.0.0.1'); // Validation $isValidEmail = GeneralUtility::validEmail('test@example.com'); $isValidUrl = GeneralUtility::isValidUrl('https://example.com'); // Hashing and security $hmac = GeneralUtility::hmac('data', 'secret'); // XML/JSON handling $array = GeneralUtility::xml2array($xmlString); // Unique ID generation $uniqueId = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Crypto\Random::class)->generateRandomHexString(32); ``` ## TCA Configuration TCA (Table Configuration Array) defines the structure, behavior, and rendering of database tables in TYPO3 backend. Configuration files are placed in `Configuration/TCA/` or `Configuration/TCA/Overrides/`. ```php <?php // Configuration/TCA/tx_myext_domain_model_blog.php return [ 'ctrl' => [ 'title' => 'LLL:EXT:my_extension/Resources/Private/Language/locallang_db.xlf:tx_myext_domain_model_blog', 'label' => 'title', 'tstamp' => 'tstamp', 'crdate' => 'crdate', 'delete' => 'deleted', 'sortby' => 'sorting', 'default_sortby' => 'title ASC', 'enablecolumns' => [ 'disabled' => 'hidden', 'starttime' => 'starttime', 'endtime' => 'endtime', ], 'searchFields' => 'title,description', 'iconfile' => 'EXT:my_extension/Resources/Public/Icons/blog.svg', ], 'types' => [ '1' => [ 'showitem' => ' --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general, title, slug, description, image, category, --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access, hidden, starttime, endtime ' ], ], 'columns' => [ 'title' => [ 'label' => 'Title', 'config' => [ 'type' => 'input', 'size' => 50, 'max' => 255, 'eval' => 'trim,required', ], ], 'slug' => [ 'label' => 'URL Slug', 'config' => [ 'type' => 'slug', 'generatorOptions' => [ 'fields' => ['title'], 'replacements' => [ '/' => '-' ], ], 'fallbackCharacter' => '-', 'eval' => 'uniqueInSite', ], ], 'description' => [ 'label' => 'Description', 'config' => [ 'type' => 'text', 'cols' => 40, 'rows' => 5, 'enableRichtext' => true, ], ], 'image' => [ 'label' => 'Image', 'config' => [ 'type' => 'file', 'maxitems' => 1, 'allowed' => 'common-image-types', ], ], 'category' => [ 'label' => 'Category', 'config' => [ 'type' => 'select', 'renderType' => 'selectSingle', 'foreign_table' => 'tx_myext_domain_model_category', 'foreign_table_where' => 'ORDER BY title', 'items' => [ ['label' => '-- Please select --', 'value' => 0], ], 'default' => 0, ], ], 'tags' => [ 'label' => 'Tags', 'config' => [ 'type' => 'select', 'renderType' => 'selectMultipleSideBySide', 'foreign_table' => 'tx_myext_domain_model_tag', 'MM' => 'tx_myext_blog_tag_mm', 'size' => 5, 'autoSizeMax' => 10, ], ], 'hidden' => [ 'label' => 'Hidden', 'config' => [ 'type' => 'check', 'items' => [ ['label' => 'Disable'] ], ], ], 'starttime' => [ 'label' => 'Start Time', 'config' => [ 'type' => 'datetime', 'default' => 0, ], ], 'endtime' => [ 'label' => 'End Time', 'config' => [ 'type' => 'datetime', 'default' => 0, ], ], ], ]; ``` ## Summary TYPO3 CMS provides a comprehensive enterprise content management platform with well-structured APIs for database operations (ConnectionPool, QueryBuilder), caching (CacheManager), MVC development (Extbase ActionController, Repository), templating (Fluid ViewHelpers), data manipulation (DataHandler), and site management (SiteFinder, PageRouter). The system is highly extensible through TCA configuration, PSR-14 events, and custom extensions. Key integration patterns include: using dependency injection via constructor arguments or `GeneralUtility::makeInstance()`, implementing Extbase controllers with proper action methods returning `ResponseInterface`, creating repositories that extend the base `Repository` class for domain object persistence, leveraging Fluid templates with ViewHelpers for frontend rendering, and configuring sites via YAML files in `config/sites/`. The codebase follows PSR standards and integrates Symfony components for routing, mail, console commands, and dependency injection.