How to change the position of a column in the TYPO3 TCA? - typo3

I want to move a column from one tab to another. Is there a better way than to rewrite the types definition manually which is not very reliant in regard to extension updates changing the TCA?

It's not 100% fail safe, since there still might be extensions messing things up, but the closest you can get will be to make use of the ExtTablesInclusionPostProcessing event and put addToAllTCAtypes into the invoke method, since this will not just add new fields but even put existing fields to another tab:
<?php
declare(strict_types=1);
namespace Vendor\Extension\EventListener;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
/**
* Class ExtTablesInclusionPostProcessing
*/
class ExtTablesInclusionPostProcessing
{
/**
* Function which may process data created / registered by extTables
* scripts (f.e. modifying TCA data of all extensions)
*
* #param AfterTcaCompilationEvent $event
*/
public function __invoke(AfterTcaCompilationEvent $event): void
{
ExtensionManagementUtility::addToAllTCAtypes('tt_content', 'fieldname', '', 'after:fieldname_in_the_other_tab');
}
}
To remove the existing field before, you could make use of this trick:
https://stackoverflow.com/a/59179916/2333754
And finally to be on the safer side you could make sure that other extensions are loaded before your own extension by putting them into the suggest section of your composer.json.

With installation of extension tcabuilder it is possible to do simple changes in the TCA.

Related

Typo3: Controller action with hidden record as its parameter

I am currently trying to get a extension working in Typo3 v10, which enables the user to show, edit, update, disable and enable other user accounts.
Unfortunately, I am running into the issue that I cannot use disabled users as arguments for the actions:
/**
* Save user changes
*
* #param \Company\MyExtension\Domain\FeUser $feuser
* #return void
*/
public function updateAction(\Company\MyExtension\Domain\FeUser $feuser): void {}
It would resulting in the error following error:
Object of type \Company\MyExtension\Domain\FeUser with identity "3" not found.
From what I have gathered, extbase does not rely on the repository's default query settings to create the objects but instead uses PersistenceManager::createQueryForType to get the query settings via QueryFactory::create. This is an issue also listed in a few bug reports.
There's a suggestions as to how to use a custom QueryFactory to set different default QuerySettings for my extension, however this does not seem to work in Typo3 v10 anymore, at least my custom QueryFactory isn't being used after registering it... Also, if this were to work, wouldn't it use the new QueryFactory for all objects instantiated through a controller action and not just this extension?
How can I properly handle hidden users my extension with Typo3 v10.4?
P.S. Another suggestion was to fetch object early through initializeAction, but this only works well if it is about the unmodified model and not when setting new values for the object, as it would just load the database values in the end...
Checkout the extension "news" how it is handled here:
if ($news === null || $this->settings['isShortcut']) {
$previewNewsId = ((int)$this->settings['singleNews'] > 0) ? $this->settings['singleNews'] : 0;
if ($this->request->hasArgument('news_preview')) {
$previewNewsId = (int)$this->request->getArgument('news_preview');
}
if ($previewNewsId > 0) {
if ($this->isPreviewOfHiddenRecordsEnabled()) {
$news = $this->newsRepository->findByUid($previewNewsId, false);
} else {
$news = $this->newsRepository->findByUid($previewNewsId);
}
}
}
https://github.com/georgringer/news/blob/master/Classes/Controller/NewsController.php#L338
I am assuming you need the URL as well. I gave an answer here if you wanna take a look.
Show, edit and update hidden records in FrontEnd (TYPO3)
You can adjust it to your own needs as well.
Best regards

TYPO3 CMS EXT:webkitpdf error CacheDatabaseBackend TYPO3 9.5

Because the famous extension webkitpdf isn't maintained anymore, I try my very best to get this working under TYPO3 9.5.
My patched version https://github.com/EnzephaloN/typo3-extension-webkitpdf worked fine til 8.7, but now I get an error in Classes/Utility/CacheDatabaseBackend.php::set
/**
* Saves data in a cache file.
*
* #param string $entryIdentifier An identifier for this specific cache entry
* #param string $data The data to be stored
* #param array $tags Tags to associate with this cache entry
* #param integer $lifetime Lifetime of this cache entry in seconds. If NULL is specified, the default lifetime is used. "0" means unlimited liftime.
* #return void
*/
public function set($entryIdentifier, $data, array $tags = array(), $lifetime = NULL) {
if ($this->maximumNumberOfEntries > 0 && !$this->has($entryIdentifier)) {
$this->removeOldEntriesIfRequired();
}
parent::set($entryIdentifier, $data, $tags, $lifetime);
}
The parent::set($entryIdentifier, $data, $tags, $lifetime); results an Cannot call abstract method TYPO3\CMS\Core\Cache\Backend\BackendInterface::set() error.
Anyone an idea how to adjust this method to TYPO3 9.5??
Tried to extend from \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend which caused a lot of trouble with different errors in backend.
For now I disabled calling parent::set(... - so it works without cache, but without errors.
In the BackendInterface the function set is defined like this:
public function set($entryIdentifier, $data, array $tags = [], $lifetime = null);
Nevertheless it never has a concrete function in class AbstractBackend in TYPO3 version 9. Probably in Version 8 that's different and the reason that it still worked.
So you've to define the function in your own class and it has to satisfy the requirements predefined in the BackendInterface like shown above.
To get an idea what the function is doing look in TYPO3 7 or 8. Even if you've to adjust it perhaps that might be useful.
EDIT:
In general to keep the call with parent::set(...); in your own function you still had to create another class. This is probably not required if you don't need the functionality additionally in another place.
In general you can just search in older versions what the function did there and integrate that functionality in your existing function set(...).

How to register modules for advanced functions

When I select Web/Functions in the menu of typo3 cms 9.5.4 backend, I get this error:
Advanced functions
No modules have been registered. Please contact your system administrator.
I am the system administrator. I can't find anywhere how to register modules. How do I register any modules?
Like Peter wrote, the Extension func was removed from core, is actually not marked as compatible with version 9.5. and should avoided to use further more.
But follow two files will help you to register your own module:
ext/extension/ext_tables.php
// Module wizard
if (TYPO3_MODE === 'BE') {
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::insertModuleFunction(
'web_func',
\Vendor\Extension\MyModuleFunction::class,
null,
'LLL:EXT:extension/Resources/Private/Language/locallang_module.xlf:mymodulefunction'
);
}
ext/extension/Classes/MyModuleFunction.php
<?php
namespace Vendor\Extension;
class MyModuleFunction
{
/**
* Initialize the object
*
* #param \object $pObj A reference to the parent (calling) object
* #throws \RuntimeException
*/
public function init($pObj)
{
// Required method
}
/**
* Checking for first level external objects
*/
public function checkExtObj()
{
// Required method
}
/**
* Main function creating the content for the module.
*
* #return string HTML content for the module, actually a "section" made through the parent object in $this->pObj
*/
public function main()
{
return '<h1>My module function</h1>';
}
}
As far as I know, EXT:wizard_crpages and EXT:wizard_sortpages are not maintained anymore in TYPO3 9.x.
EXT:func has been moved to the TYPO3 Extension Repository to preserve the possibility to register your own wizards.
UPDATE:
The possibility to create multiple pages and to sort pages is now available via the context menu in the page tree. Just do a left or right click on the icon in front of any page and choose More options ... from the context menu.

showAction : finding fe_user entry by username instead of uid

I created my own (Typo3 6.2) extension with the Extension Builder to extend fe_users and all is working fine but I would like to be able to use the showAction based on the username instead of the uid of the user.
The goal is simply to be able to call the controller on the frontend like this:
my.domain.com/users?tx_crilcq_crilcqmember[username]=johndoe&tx_crilcq_crilcqmember[action]=show
instead of this:
my.domain.com/users?tx_crilcq_crilcqmember[member]=2&tx_crilcq_crilcqmember[action]=show
At first I thought that I had to modify the extended repository (class MemberRepository extends \TYPO3\CMS\Extbase\Persistence\Repository) but it seems that it is used for requests returning an array of entries and not to reference a single instance. Don't know if I'm right about this but my feeling is that the thing I need to modify is somewhere else.
Any clue someone?
An Extbase repository has magic methods findBy[property], findOneBy[property] and countBy[property], that returns/counts objects by the given property.
You can change your show action as shown below:
/**
* #param string $username
* #return void
*/
public function showAction($username) {
$user = $this->memberClassRepository->findOneByUsername($username);
$this->view->assign('user', $user);
}

Joomla 3.1.5 Saving tags to ucm_content and contentitem_tag_map

I have spent days on this one so I have put my hand up. I am implementing tags in my own component and have followed Elin's instructions on the Joomla site to the letter (27 July 2013). I can get the new tags to save in the TAGS table correctly, but not the UCM or TAG MAP tables as all the standard components do.
I have traced the code all the way through, and compared to the com_contacts, and cannot for the life of me see any difference in my component.
Where should I be looking for where the code updates the other two tables? I know this will end in an embarrassing answer but I am happy to look foolish.
My table does not have meta fields, but I have manually fudged the metadata array in the $data array. Any help is appreciated.
Instructions:http://docs.joomla.org/J3.1:Using_Tags_in_an_Extension
After many days of extra frustration I discovered that for my component I had to include the archived information into my table class, that is not supposed to be required any more.
Add a property
/**
* Indicator that the tags have been changed
*
* #var JHelperTags
* #since 3.1
*/
protected $tagsHelper = null;
This property helps to manage change in tags.
Modify your constructor
Follow this example to modify your consructor which provides substantial reduction in duplicate code.
$this->tagsHelper = new JHelperTags();
$this->tagsHelper->typeAlias = 'com_contact.contact';
Modify your store() method
Management of tagging and associated data is largely handled through the store() method. This provides maximum flexibility for the handling of tags across many extensions.
If you don't have a store() method you will need to add one. The assumption is that tables will inherit from JTable.
The handling involves preStoreProcess(), a call to the parent store() method, and then a postStoreProcess().
$this->tagsHelper->preStoreProcess($this);
$result = parent::store($updateNulls);
return $result && $this->tagsHelper->postStoreProcess($this);