typo3extbasetypo3-7.xtypo3-extensions

How does my extension read bodytext fields from tt_content in TYPO3 CMS 7.6?


I'm writing a TYPO3 extension using TYPO3 CMS 7.6.x LTS and Extension Builder. One of my extension's tasks is to scan through the "header" and "bodytext" fields of TYPO3's tt_content table; match specific text patterns in "bodytext"; parse the found text; and put the resulting data into my extension's log table along with a label from the tt_content "header" field.

"Using Foreign Data Sources" in "Developing TYPO3 Extensions with Extbase and Fluid" at [ https://docs.typo3.org/typo3cms/ExtbaseFluidBook/6-Persistence/4-use-foreign-data-sources.html ] talks about putting data INTO tt_address using a TypoScript mapping. Instead, I'm reading data FROM tt_content, and would rather stay within PHP in the extension.

Using the graph in Foreign Key to TYPO3 Frontend User as an example, I added a second model to my extension's domain model in Extension Builder. I made a "TtContent" model, and used its "Domain object settings" to "map to existing table", its entry being "tt_content". I did NOT enter a value into the "extend using model class" field. I made a "relation" field in my Log model, and ran a wire connected from my Log:ttContent relation field to the title bar of my TtContent model. When I then clicked "Save", Extension Builder replied: "The configuration for table "tt_content" is not compatible with extbase. You have to configure it yourself if you want to map to this table (Error 606)". I don't understand this error message.

In Extension Builder, do I make a relation in my Log model to an existing external class? If so, which external class do I use? Or, do I make a model of tt_content in Extension Builder, and somehow get through that error 606? It shouldn't seem hard to do, because I want to read from an existing table already in TYPO3.


Solution

  • Solution: Create an Extbase model and a repository representing the existing tt_content table, then write a TypoScript property mapping.

    In TYPO3 Extension Builder's domain modeller, add a model called "Content" or some name that reminds you of the tt_content table. In the "domain object settings" part of your Content model, put "tt_content" in the "map to existing table" box. Nevermind the "extend existing model class" box, because Extbase doesn't have such a class for tt_content.

    Also in the domain object settings, set object type to "Entity", check the "is aggregate root" box, and uncheck the "add deleted field", "add hidden field", "add starttime/endtime fields", and "enable categorization" boxes. Setting the object type to "entity" and checking the "is aggregate root?" box causes Extension Builder to create a repository for your Content model.

    Add properties to your Content model that represent the columns you want to access in the tt_content database table. In my Content model, I added only "header" and "bodytext" properties.

    Note: You need not add TYPO3's uid or pid properties to the Content model. These properties have been extended from the parent \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject class.

    Click "Save" in Extension Builder to save your new domain model. You will receive a message: "Warning! The configuration for table "tt_content" is not compatible with extbase. You have to configure it yourself if you want to map to this table (Error 606). Do you want to save anyway?" Yes, save anyway. Extension Builder will respond, "Success. The Extension was saved. Your Extension is not installed yet." Exit Extension Builder.

    Note: If you go through several modelling iterations in Extension Builder, you may find artifacts in the extension's final code, left over from your earlier iterations. Extension Builder overwrites some of your extension areas, but leaves other areas alone. See the Extension Builder configuration reference at [ https://docs.typo3.org/typo3cms/extensions/extension_builder/Configuration/Index.html ].

    Use Extbase table mapping to configure and thereby access content from the TYPO3 tt_content table. Do this configuration with TypoScript "config.tx_extbase.persistence.classes" mapping parameters in the "typo3conf/ext/yourextensionkey/ext_typoscript_setup.txt" file. Extension Builder created this file when you saved your domain model. This is the configuring mentioned in Error 606.

    See the code example in "Using Foreign Data Sources" at [ https://docs.typo3.org/typo3cms/ExtbaseFluidBook/6-Persistence/4-use-foreign-data-sources.html ]. This TypoScript code example defines the mapping lines themselves. You may wish to use "config.tx_extbase" instead of "plugin.tx_myextension". The next page, "Modeling the Class Hierarchy" at [ https://docs.typo3.org/typo3cms/ExtbaseFluidBook/6-Persistence/5-modeling-the-class-hierarchy.html ], has a code example for "config.tx_extbase"; but it doesn't show the mapping lines themselves.

    In my situation, I added TypoScript instructions in ext_typoscript_setup.txt to map the "header" and "bodytext" columns. I also deleted the recordType = Tx_Myextensionkey_Content line that Extension Builder wrote, because I want to read tt_content records that already exist, not records made by my extension.

    config.tx_extbase{
        persistence{
            classes{
    
                Mynamespace\Myextensionkey\Domain\Model\Content {
                    mapping {
                        tableName = tt_content
                        columns {
                            header.mapOnProperty = header
                            bodytext.mapOnProperty = bodytext
                        }
                    }
                }
    
            }
        }
    }
    

    My TYPO3 extension can now read from tt_content.

    Note: Giving a value to recordType in ext_typoscript_setup.txt causes the Extbase persistence layer to search for that one value in the underlying tt_content.CType column. Extbase does this through its \TYPO3\CMS\Extbase\Configuration\AbstractConfigurationManager getConfiguration() $frameworkConfiguration array, and its \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory buildDataMapInternal() function. As of this writing, you cannot use a wildcard character such as * or % in your recordType value; and you cannot give a value list such as text, textmedia.