How to register modules for advanced functions - typo3

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.

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.

PHP Intellisense in Visual Studio Code

I'm using Visual Studio Code to develop in PHP, and I've been having some trouble getting Code to provide the proper intellisense results. For example, this newly created Codeception unit test:
<?php
class MyTest extends \Codeception\Test\Unit
{
/**
* #var \UnitTester
*/
protected $tester;
protected function _before()
{
}
protected function _after()
{
}
// tests
public function testSomeFeature()
{
$this->assertFalse(false);
}
}
When I type $this-> I expect to see assertFalse, assertTrue, and all the other methods provided by \Codeception\Test\Unit. But what I get is basically whatever items exist within the current file and that's it.
What can I do to get all the methods from the Unit class to show up? I already have the PHP IntelliSense extension installed, v2.3.4.
Visual Studio Code core does not include advanced PHP features, just syntax highlighting, simple code completion and code linting provided by the PHP binary as long as you have it installed. In short, the features you can configure with these directives:
// Controls whether the built-in PHP language suggestions are enabled. The support suggests PHP globals and variables.
"php.suggest.basic": true,
// Enable/disable built-in PHP validation.
"php.validate.enable": true,
// Points to the PHP executable.
"php.validate.executablePath": null,
// Whether the linter is run on save or on type.
"php.validate.run": "onSave"
For anything else you need to install a third-party extension.
My personal choice is PHP Intelephense. In particular, it supports docblock annotations, including magic properties:
/**
* #property string $foo
*/
class Bar
{
}
... and inline types:
/** #var \Database $db */
$db->connect();

Call to private PHPExcel_IOFactory::__construct() from context - TYPO3

Hi have to create an excel export using phpexcel library. So I copy the library in my class then write the following code in my controller
require_once PATH_site . 'typo3conf/ext/extension_name/Classes/Library/PHPExcel/IOFactory.php';
public function excelTest()
{
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');
$objReader = $objectManager->get('PHPExcel_IOFactory');
}
But it return an error
Fatal error: Call to private PHPExcel_IOFactory::__construct() from
context 'TYPO3\CMS\Core\Utility\GeneralUtility' in
/opt/lampp_repository/lampp-5.6/htdocs/typo3_src-7.6.6/typo3/sysext/core/Classes/Utility/GeneralUtility.php
on line 4533
Don't include the library yourself, TYPO3 has dependency injection for that. All the php files in your Extension directory will be indexed, and all Classes inside will automatically be available, you just have to make sure, that your class cache is fresh, if in doubt by manually deleting the typo3temp/Cache/Code/ClassLoader* file.
If you want to include en external class into your own namespace, you have to hint Extbase as to how to include it, with an ext_autoload.php file, because if multiple extensions load code into the same class namespace they will collide.
It also is good practice not to inject the class itself, but an Abstrct that extends upon it, so you can customize it in an isolated manner that doesn't modify the vendor files.
Heres my approach to it:
Put all files of PHPExcel into yourextension/Classes/Vendor/PHPExcel.
Create a new file yourextension/Classes/Vendor/PHPExcel.php:
<?php
namespace Vendorname\Extensionname\Classes;
/*
* PhpExcel
*/
class PhpExcel implements \TYPO3\CMS\Core\SingletonInterface extends \PHPExcel {
// Differences from the original implementation, e.g. a writer that generates
// a filename and puts the Excel file into typo3temp
}
You should then be able to just inject the class #inject-Annotation in your ActionController:
/**
* PhpExcel
*
* #var \Vendorname\Extensionname\Classes\PhpExcel
* #inject
*/
protected $phpExcel;
Further reading:
https://wiki.typo3.org/Dependency_Injection
https://docs.typo3.org/typo3cms/CoreApiReference/ApiOverview/Autoloading/Index.html

TYPO3: How to use storage pid from pagetree in backend module?

I created an extension using Extension Builder, and included a backend module, under the web section. In the generated code, there are two constants for the storage pid: one for plugins and one for modules.
Now I like my module to use the storage pid from the selected page or folder in the pagetree, like page, list, or template modules do. How can I use storage pid from pagetree instead of using a constant, in a backend module?
To get the selected page from the page tree in your backend module, one way is to simply get the id param, ideally in your initializer.
Since extbase reads the storage pid from your module (or plugin for the frontend) settings, you can just override the storagePid part so you don't have to set the pid for each query / otherwise in your repositories.
The following should work. However, I use this in a CommandController and not in a controller used in the backend. I hadn't to change anything there because the repositories automatically scoped records to the selected page.
class Tx_MyExt_Controller_BackendController extends Tx_Extbase_MVC_Controller_ActionController {
/**
* #var Tx_Extbase_Configuration_ConfigurationManagerInterface
* #inject
*/
protected $configurationManager;
/**
* #var int Current page
*/
protected $pageId;
/**
* Action initializer
*
* #return void
*/
protected function initializeAction()
{
$this->pageId = (int)t3lib_div::_GP('id');
$frameworkConfiguration = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
$persistenceConfiguration = array('persistence' => array('storagePid' => $this->pageId));
$this->configurationManager->setConfiguration(array_merge($frameworkConfiguration, $persistenceConfiguration));
}
}

Using WindowBuilder in Eclipse to add SWT TableView window to existing program

I've installed WindowBuilder in Eclipse Juno and am able to create Details Page. The generated source code:
/**
* Initialize the details page.
* #param form
*/
public void initialize(IManagedForm form) {
managedForm = form;
}
/**
* Create contents of the details page.
* #param parent
*/
public void createContents(Composite parent) {
FormToolkit toolkit = managedForm.getToolkit();
parent.setLayout(new FillLayout());
//
requires a ManagedForm to be initialised. A a very Java newbie I've been completely stuck as to where to get this object. I've probably missed the obvious but help would be very much appreciated.
Check out the ManagedForm class. Create a new class that inherits from ManagedForm and you got yourself an IManagedForm implementation:
public class MyManagedForm extends ManagedForm {
public MyManagedForm(Composite parent) {
super(parent);
}
}
I'd recommend using an Editor like Eclipse and getting the source code into it so that you can easily browse the documentation and the API's classes in general. Lars Vogel's introduction to Eclipse APIs is a good read, too.