TYPO3 CMS EXT:webkitpdf error CacheDatabaseBackend TYPO3 9.5 - typo3

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

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

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);
}

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.

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);