How to debug `Validation failed while trying to call showAction` in another extension in TYPO3 - typo3

I am getting Validation failed while trying to call showAction in another extension, but due to an extension I developed. Now I dont know where / how to debug the issue. Something tells me it should be in the setup.txt
Is it possible that my extension is somehow conflicting with this other extension? Because if my extension is deactivated then this error disappears. So then how do I debug where the problem could be in my extension?

This error is occuring when a model which is handed over as parameter is not valid.
E.g. public function showAction(\Vendor\ExtName\Domain\Model\MyClass $myClass), Extbase tries to validate the model $myClass.
You can either look why the model is not valid (preferred way) or you can say Extbase to not validate the class by adding #ignorevalidation $myClass to the function header:
/**
* #param \Vendor\ExtName\Domain\Model\MyClass $myClass
* #ignorevalidation $myClass
*/
public function showAction(\Vendor\ExtName\Domain\Model\MyClass $myClass)
{
...
}
When you want to look for the possible invalid entry you need to check the code of the model. More you can find here: https://docs.typo3.org/typo3cms/ExtbaseFluidBook/9-CrosscuttingConcerns/2-validating-domain-objects.html

Related

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

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.

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(...).

"Oops, an error occurred! Code: 201601301501048.." in TYPO3 7.6

I installed the TYPO3 version 7.6 and after adding extension to my page I got the error:
"Oops, an error occurred! Code: 201512031647523f4d731f"
I am not getting meaning of this error and I also enable 'displayErrors' => 1, in local configuration but still not get meaningful error.
You need to switch off the "Content Object Exception Handler", which is an exception handler in new versions. If a content element/plugin throws an exception, it does no longer take down the whole site, but only itself. To disable it, set
config.contentObjectExceptionHandler = 0
Reference
Don't forget to re-enable the exception handler when going live, and in your live system, you can find the exception trace in your log files. Basically what Viktor Livakivskyi says in the other answer.
Basically it is date + hash, which makes each of such errors unique.
For development environment you may turn it off, as #Jost suggested.
But for production this is crucial to let it be turned on, so if some of your plugins or TS libs fails, it will not break the complete output and show "Oops an error occurred" without any info, but the message, you see now with a code.
The real user of a website can then report this code to you, and you can search for this code in your TYPO3 error log, which is by default located under typo3temp/logs/, unless you configured it different.
So, this feature really easies your life to find out user-generated errors.
You can open the file ./typo3/sysext/frontend/Classes/ContentObject/Exception/ProductionExceptionHandler.php
Search for the string Oops, an error occurred!.
Add a debug line directly after the function declaration.
/**
* Handles exceptions thrown during rendering of content objects
* The handler can decide whether to re-throw the exception or
* return a nice error message for production context.
*
* #param \Exception $exception
* #param AbstractContentObject $contentObject
* #param array $contentObjectConfiguration
* #return string
* #throws \Exception
*/
public function handle(\Exception $exception, AbstractContentObject $contentObject = null, $contentObjectConfiguration = array())
{
debug ($exception, 'handle $exception');
Then you use a debug extension, e.g. fh_debug.
This will give you an output like this. It shows you the backtrace of the call which lead to this error. The backtraces are shown in 2 formats. You can add more debug lines at the positions before the places from the backtraces, in order to have more information about the error.
<table><tbody><tr><td>index.php</td><td>34</td><td>call_user_func</td></tr><tr><td>index.php</td><td>33</td><td>run</td></tr><tr><td>Application.php</td><td>78</td><td>handleRequest</td></tr><tr><td>Bootstrap.php</td><td>302</td><td>handleRequest</td></tr><tr><td>RequestHandler.php</td><td>232</td><td>INTincScript</td></tr><tr><td>TypoScriptFrontendController.php</td><td>3478</td><td>recursivelyReplaceIntPlaceholdersInContent</td></tr><tr><td>TypoScriptFrontendController.php</td><td>3512</td><td>INTincScript_process</td></tr><tr><td>TypoScriptFrontendController.php</td><td>3564</td><td>cObjGetSingle</td></tr><tr><td>ContentObjectRenderer.php</td><td>859</td><td>render</td></tr><tr><td>ContentObjectRenderer.php</td><td>943</td><td>render</td></tr><tr><td>ContentObjectArrayContentObject.php</td><td>41</td><td>cObjGet</td></tr><tr><td>ContentObjectRenderer.php</td><td>805</td><td>cObjGetSingle</td></tr><tr><td>ContentObjectRenderer.php</td><td>859</td><td>render</td></tr><tr><td>ContentObjectRenderer.php</td><td>953</td><td>handle</td></tr><tr><td>ProductionExceptionHandler.php</td><td>53</td><td>debug</td></tr></tbody></table><br><table><tbody><tr><th>Object TYPO3\CMS\Core\Error\Exception</th></tr><tr><td>message</td><td class="el">PHP Catchable Fatal Error: Argument 1 passed to TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::render() must be an instance of TYPO3\CMS\Frontend\ContentObject\AbstractContentObject, null given, called in /home/myuser/public_html/neu/typo3_src-7.6.10/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php on line 1359 and defined in /home/myuser/public_html/neu/typo3_src-7.6.10/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php line 927</td></tr>
<tr><td>code</td><td class="el"><table><tbody><tr><th>Integer</th></tr><tr><td>1</td></tr></tbody></table></td></tr>
<tr><td>file</td><td class="el">/home/myuser/public_html/neu/typo3_src-7.6.10/typo3/sysext/core/Classes/Error/ErrorHandler.php</td></tr>
<tr><td>line</td><td class="el"><table><tbody><tr><th>Integer</th></tr><tr><td>111</td></tr></tbody></table></td></tr>
</tbody></table>
<h3>handle $exception</h3><hr>
Text, added later: In the meantime it is not necessary any more to edit the PHP file ProductionExceptionHandler.php of TYPO3. You just install and configure the extension fh_debug which now does the necessary step automatically.

Get List of TYPO3 FE_User Group

How can I get a list with all my frontenduser groups?
I've tried this:
/**
* feUserGroupRepository
*
* #var \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserGroupRepository
* #inject
*/
protected $feUserGroupRepository = NULL;`
and then this:
$usergroups = $this->feUserGroupRepository->findAll();
I got this error: Call to a member function findAll() on a non-object
And I tried this way:
/**
* #var \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserGroupRepository $feUserGroupRepository
*/
$feUserGroupRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Domain\\Repository\\FrontendUserGroupRepository');
$allUsers = $feUserGroupRepository->findAll();`
dosn't work at all i've got this error message
PHP Catchable fatal error: Argument 1 passed to
TYPO3\CMS\Extbase\Persistence\Repository::__construct() must implement interface
TYPO3\CMS\Extbase\Object\ObjectManagerInterface, none given, called in
C:\xampp\htdocs\typo3\typo3\sysext\core\Classes\Utility\GeneralUtility.php on
line 4431 and
defined in C:\xampp\htdocs\typo3\typo3\sysext\extbase\Classes\Persistence\Repository.php
How can I get a list with all feusergroups?
Rcord Type?
The error indicates that the Dependency Injection didn't work. Please make sure that you flush the System Cache after doing changes that are cached in the Database, which is the case for changes of class names or changes that require dependencies to be rebuilt.
You can flush the system cache in the Install Tool ("Important actions") or directly in the Backend if you are running TYPO3 in Development context. "Flush general caches" does not (!) flush the database-based system caches.
Depending on the TYPO3 version you're running, you will need to set the Record Type of your Frontend Usergroups (column "tx_extbase_type") to FrontendUserGroup.
Using makeInstance for generating an instance of a Repository is discouraged. You should use dependency injection where possible (in this case it is), or, where not possible, the ObjectManager.