I'm trying to develop an extension that adds a Button to the ClearCache menu in the TYPO3 Backend. In a large installation with multiple domains, non-admin users need a button to clear the page cache for their domain, but only of those pages that they have access to. The default options.clearCache.pages = 1 instead flushes the whole Frontend Cache of the installation.
I've gotten so far as to calling a method in a custom class ClearCacheHook, that implements \TYPO3\CMS\Backend\Toolbar\ClearCacheActionsHookInterface.
I next need to get a list of all page uids the BackendUser has access to, which is done with $backendUser->getDbMountPoints(). All the docs speak of a global variable $BE_USER, but this isn't set for me. I have a $GLOBALS['BE_USER'], but that is of the class BackendUserAuthentication.
I can't figure out how to resolve the BackendUser from the BackendUserAuthentication. Theres the BackendUser uid in the object so I tried initializing a TYPO3\\CMS\\Beuser\\Domain\\Repository\\BackendUserRepository via the ObjectManager, but that fails.
I'll focus on the more specific tasks: Create an instance of BackendUserRepository and create an instance of BackendUser from uid.
You might have a look at the UsernameViewHelper.php class of be_log in the TYPO3 core.
specifically this:
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Domain\Repository\BackendUserRepository;
use TYPO3\CMS\Extbase\Object\ObjectManager;
...
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$backendUserRepository = $objectManager->get(BackendUserRepository::class);
/** #var \TYPO3\CMS\Extbase\Domain\Model\BackendUser $user */
$user = $backendUserRepository->findByUid($uid);
If there is something, I don't find in the documentation, I sometimes look at existing extensions. A good candidate is the news extensions. Other good candidates are, of course, the TYPO3 source code.
Related
I am trying to find a solution to what seems to be a FPC-linked issue.
In my code I am using the following method in order to get the current product ID from a Product page.
$this->catalogSession->getData('last_viewed_product_id')
This worked just fine until I tried it on a website with Full Page Cache: in this case, it returns an empty value (maybe because the session data cannot be accessed from cache).
Does anyone know an alternative method to get the product ID from the current context?
I have tried this alternative synthax:
$_SESSION['catalog']['last_viewed_product_id'];
While not the best solution and definitely not best practice, you can use objectmanager:
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$product = $objectManager->get('Magento\Framework\Registry')->registry('current_product');
$id = $product->getId();
This will get you the id but, as stated above, it's not suggested and you should create a block and inject the registry there and call it in your code.
You can see this post https://meetanshi.com/blog/get-current-product-id-in-magento-2/
GET and POST parameters in custom extbase controllers need to be prefixed with the plugin signature to be injected automatically:
<?php
namespace Vendor\Example\Controller;
class SearchController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
{
public function resultsAction($q = null)
{
//...
}
}
Search term $q is only filled automatically if it is passed as ?tx_example_search[q]=foo.
Is there a way declare that the readable version ?q=foo is also fine, and that this should be injected by extbase as well?
(I know that this breaks when multiple plugins on the same page use that parameter, but that's no problem here.)
(The parameter mapping seems already done when ActionController::processRequest() is called, so it must be done earlier.)
You could use the Extbase Plugin enhancer within the routing configuration.
See here: TYPO3 Advanced routing configuration Docs
TYPO3 would then transform the EXTbase URLs into an readable version.
Example:
without the routeEnhancer: yourdomain.com/?tx_example_search[q]=foo
with the routeEnhancer: yourdomain.com/foo
Tipp: You have to define all GET Params otherwise TYPO3 will show the cHash Param.
You can use the method \TYPO3\CMS\Core\Utility\GeneralUtility::_GP($var) in order to retrieve parameters from global variables GET/POST.
Or also \TYPO3\CMS\Core\Utility\GeneralUtility::_GET($var) or \TYPO3\CMS\Core\Utility\GeneralUtility::_POST($var).
Take care of security, those parameters are not sanitized !
If you really want to add the parameter to the action, you have to create an initializeAction() and set the parameter, something like this I guess :
public function initializeResultsAction() {
$myVar = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('q');
$this->request->setArgument('q', $myVar);
}
I need to include a PHP script in my TS template :
page {
10 = USER_INT
10.includeLibs = lib_confidential.php
10.userFunc = MyClass->ConfidentialRequest
}
It works perfectly but I would like to locate the lib_confidential.php outside of my website root directory (and make something like 10.includeLibs = ../lib_confidential.php). Is it possible to secure my PHP script and how to ? I thought about creating a symlink but that doesn't give any solution.
As your installation needs an update you will have to change the mechanism for including php-functions for the future.
since TYPO3 8 you need to have a class for your php functions. So the autoloader can identify the class and execute the function you need to place the class inside of an extension or declare the class to the autoloader.
Best practice would be site extension where you configure your installation, there you can havea class with all the functions you need.
examples can be found in the manual.
In an extbase extension built with extension builder on TYPO3 6.1.7, I haven't set any storagePid via Typoscript.
But I have set the "Record Storage Page" in the plugin:
I would expect that it would now only fetch records from this page.
But it doesn't, it just returns all items from that table.
How do I make the extension recognize the setting from the plugin?
Or (if it's supposed to do that out of the box) how do I find out why it doesn't?
I did a lot of research when my extension's frontend plugin (TYPO3 7.6.4) refused to use the 'pages' field of the plugin ("Record Storage Page"), so I would like to share my findings:
My extension's name is 'tx_dhsnews', my plugin's name is 'infobox'
setRespectStoragePage must be set to true (default): $query->setRespectStoragePage(TRUE)
In the typoscript-setup, the plugin-specific storagePid plugin.tx_dhsnews_infobox.persistence.storagePid MUST NOT be present at all! Not even with an empty value! Else the 'pages'-field will not be respected!
That's all. The Extensions Builder just created a typoscript-setup with the storagePid for the specific plugin 'infobox' set to nothing. That resulted in the plugin not respecting the 'pages' - field.
It's no problem to set the storagePid on extension-level (e.g. 'tx_dhsnews..persistence.storagePid'), the value will be merged with the value(s) given in 'pages' ("Record Storage Page"), but as soon the plugin-specific tx_[extension]_[plugin].persistence.storagePid exists in the typoscript, it will overrule everything else!
Hope this will help somebody to save some time + nerves
Add the following code to your repository
namespace <Vendor>\<Extkey>\Domain\Repository;
class ExampleRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
// Example for repository wide settings
public function initializeObject() {
/** #var $defaultQuerySettings \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings */
$defaultQuerySettings = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Typo3QuerySettings');
// add the pid constraint
$defaultQuerySettings->setRespectStoragePage(TRUE);
}
// Example for a function setup changing query settings
public function findSomething() {
$query = $this->createQuery();
// add the pid constraint
$query->getQuerySettings()->setRespectStoragePage(TRUE);
// the same functions as shown in initializeObject can be applied.
return $query->execute();
}
}
You will find more informations at this page
http://forge.typo3.org/projects/typo3v4-mvc/wiki/Default_Orderings_and_Query_Settings_in_Repository
I actually modified my MVC controller to achieve a record filtering depending on the actual page(storagePid==page.id).. looked like this:
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
class MyMVCController extends ActionController {
protected function initializeAction() {
parent::initializeAction();
//fallback to current pid if no storagePid is defined
$configuration = $this->configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
if (empty($configuration['persistence']['storagePid'])) {
$currentPid['persistence']['storagePid'] = GeneralUtility::_GP('id');
$this->configurationManager->setConfiguration(array_merge($configuration, $currentPid));
}
[..]
I used the solution by http://wiki.t3easy.de/ and modified the value of the storagePid cause i developed a backend module.
His tscript example didnt worked for me..
Also an article by Thomas Deuling was interesting for the topic..
but i still dont get the whole connection into my mind.. wanna go back to symfony xD
edit: for the modification of the repo queries also this article looked interesting:
https://forge.typo3.org/projects/typo3v4-mvc/wiki/Default_Orderings_and_Query_Settings_in_Repository
I want to customize Surf Platform Root-Scoped API specifically user object. That means add new property or method to user object to check the user is in certain group in header.inc.ftl [in share] like `<#if user.isAdmin>
How can I implement this?
Is Alfresco Root Scoped Objects can be used as Surf Platform Root-Scoped object?
I have no idea of customizing surf platform root object. Can anyone help me???
Not quite sure what you are trying to accomplish, but the role security model is hardcoded in spring-surf/spring webscripts. There is guest, user and admin. If what you want is another analogous role you'll have to hack the spring-surf libaries, namely:
org/springframework/extensions/surf/mvc/PageView.java
org/springframework/extensions/webscripts/ScriptUser.java
org/springframework/extensions/webscripts/Description.java
org/springframework/extensions/webscripts/connector/User.java
This is what I had to do to implement user.isEmployee. This approach allows you to literally treat your new role just as the others.
you can use
<authentication>employee</authentication>
in page descriptors or
<item type="link" permission="employee" id="people">/people-finder</item>
on the navigation.
Just checking whether the user is in a certain group in a certain webscript is a whole diffrent story and does not provide the same functionality.
If what you want is the latter, you should make a call to
/alfresco/service/api/groups/{shortName}
miss
and works through the response.
Update: The item permission attribute requires a little more tweaking.
In header.get.js, propagate the new role to it gets processed properly in header.inc.ftl:
model.permissions =
{
guest: user.isGuest,
admin: user.isAdmin,
employee : user.isEmployee
};
you could try (in JavaScript I managed something like) this:
user = Application.getCurrentUser(context);
String userName = user.getUserName();
user.isAdmin() >>> result return true if user logining is admin
or in JSP:
#{NavigationBean.currentUser.admin == true}
Sorry, i noticed now you was talking about Surf Platform root objects, but the link you put there, is deprecated for Alfresco versions above 3.3. You still use something so old?
If you manage to use JavaScript API's you could use "person" root object, with boolean isAdmin().