How to call a class into my extension using autoload. I am using typo3 7.6. From the tutorials I understood that, for typo3 7.6, this can be done in ext_emconf.php file. How to write the same in ext_emconf.php??
My class file is in Classes/class.x.php.
All classes are automatically registered in an autoload function as long as you follow the code conventions:
https://docs.typo3.org/typo3cms/ExtbaseFluidBook/a-CodingGuidelines/Index.html
class.x.php is not a valid filename for a class in Extbase. If you want to create a ClassX then the filename has to be:
/your_extension/Classes/ClassX.php
<?php
namespace YourName\YourExtension;
class ClassX {
}
Note that the extension name also turns in UpperCamelCase. For the vendor part (YourName in the example) you can chose anything that is valid in PHP.
now you can access you class with
$test = new \YourName\YourExtension\ClassX();
Your extension obviously needs to be installed to work.
!!! Keep in mind, that Typo3 only generates the autoload cache when you install / uninstall an extension. If you add new files to an already installed extension you have to delete this cache file manually
/typo3temp/autoload/autoload_classmap.php
To configurate autoloading of classes that do no match the default naming you can create an ext_autoload.php in your extension. Inside the code looks like that:
<?php
return array(
'Tx_SomeExtension_Someclass' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('some_extension') . 'pi1/someclass.php',
);
If you are developing for Typo3 7.x, keep in mind that pibased is outdated and is only supported with the compatibility extension that brings a lot of drawbacks in performance. I would recommend not to use pibased extension any more.
Related
Im upgrading an extension to work with TYPO3 v10. Since command controllers can not be used anymore, im migrating them to symfony commands as pointed by the documentation. Everything works smooth as heck except for the usage of extbase repository classes. No matter what i query, i never get a result. Since i can't find any useful information on the web and the documentation i hope this may be just something minor.
After debugging for a while i found out that the pid is not determined correctly while building the query settings. I find that kind of strange since my root template has these lines:
plugin.tx_myext.persistence.storagePid = 15403
module.tx_myext.persistence.storagePid = 15403
The repository instances are correctly injected by injectMyRepository() methods. I've tried using the extbase ObjectManager to fetch the class instances instead but the "error" stays the same.
Am i doing something wrong or is it not possible to use extbase repository classes in symfony commands?
After more research i found out that there is some bootstraping missing which results in extension settings (the storageID in my case) not being loaded. From what i've been reading, that behaviour seems intended to prevent extbase booting, i guess?
There is a reference to something similiar in the official documentation: https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/CommandControllers/Index.html#initialize-backend-user
Knowing that, i tried to find a method to initialize the missing settings which i could not find. So this does indeed seem like a missing feature.
I developed a workaround which i'm not too proud of, but it's better than nothing (or rebuilding everything to doctrine for that matter). If you stumble upon the same issue, here you go. Just insert and call this method before you fire your query:
public static function initializeConfigurationManager(): void
{
/** #var ConfigurationManager $configurationManager */
$configurationManager = GeneralUtility::makeInstance(ConfigurationManager::class);
$tmpConfiguration = $configurationManager->getConfiguration(
ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK,
'myExtensionName'
);
$configurationManager->setConfiguration($tmpConfiguration);
}
That approach exploits the singleton state of the ConfigurationManager. You simply inject the static template of your extension manually and every extbase compound (like repositories) will then use these settings from there on. Lovely.
Be aware however, this is prone to break with future internal changes.
I just had an error because of this:
Fatal error: Cannot use TYPO3\CMS\Core\Utility\GeneralUtility
as GeneralUtility because the name is already in use
in /var/www/mysite/public/typo3temp/var/cache/code/cache_core/ext_localconf_feb178af00fe22e00dc62d7dcd6d4d16f5d4fc3a.php
on line 4508
Reason was the following line in a file ext_localconf.php of an extension:
use TYPO3\CMS\Core\Utility\GeneralUtility;
Apparently, some extensions use "use" in ext_localconf.php on my system. As this is all concatenated into one file in the cache, this can lead to multiple use statements.
Is there still some way to use "use" without causing these errors? What is the recommended way?
Update: As stated in the answer by Rudy, since TYPO3 v11, it is possible to use "use" also in ext_localconf.php, ext_tables.php etc.
Updated for TYPO3 11: With 11.4 the files ext_localconf.php and ext_tables.php are scoped into the global namespace on being warmed up from the cache. Therefore use statements can now be used inside these files.
https://docs.typo3.org/m/typo3/reference-coreapi/11.5/en-us/ExtensionArchitecture/ConfigurationFiles/Index.html
For older versions < v11:
use used for importing/aliasing namespaces in PHP can only be used in global scope, not in block scope. See https://www.php.net/manual/en/language.namespaces.importing.php#language.namespaces.importing.scope. So you shouldn't use use at all in ext_localconf.php and just use full namespaces instead.
If there are extensions that do use use in ext_localconf.php you should let the maintainers of that extension know this is wrong and can (and will) cause fatal errors.
How can I autoload a hook in TYPO3?
I register it in the ext_localconf.php, but it does not get autoloaded (unless I 'include' it in the same file which is of course an extremely ugly solution).
I looked into other extensions but I don't find, where the require there hooks.
Shouldn't it be autoloaded in the ext_emconf?
'autoload' => [
'psr-4' => [
'ID\\IndexedSearchAutocomplete\\' => 'Classes'
],
],
But when don't use my ugly solution I get the error, that GeneralUtility::makeInstance can't find my file.
Does this help? http://insight.helhum.io/post/130876393595/how-to-configure-class-loading-for-extensions-in
This article describes the options you have regarding class loading.
You may want to check whether your class fulfills the psr-4 standard: http://www.php-fig.org/psr/psr-4/
I assume that you are using composer in your project. Composer does the whole autoloading of classes. It "knows" all classes of extensions that were required by composer (listed in the require part of your composer.json).
Of course you can add extensions to your project without requiering them with composer. I guess, that is what you did here. In that case you have to tell composer about the classes in your composer.json.
Add a autoload section:
"autoload": {
"psr-4": {
"ID\\IndexedSearchAutocomplete\\": "web/typo3conf/ext/indexed_search_autocomplete/Classes"
}
}
Of course your FQCN have to match the path above your Classes folder (that is what psr-4 means).
After that you can type composer dump-autoload and your class should be loaded.
I want to modify the code for the Order/Sales table in the admin interface and the PDF generation code without alterting the files in the core directory. How do I do this? I understand that I have to create a new module that uses the same paths as the files I want to overwrite, but I'm not sure what else I have to do...are there some special steps to go through for the config.xml of the module??
If you want to do it in a separate module, you should put your new model (block, helper or whatever you need to override - I'll be using the model example, its the same for the others - only the controllers are quite different) in the 'Model' directory (for instance: code/local/MyNamespace/MyModule/Model/Sales/Order.php). In your modules config.xml you should add:
<global>
(...)
<models>
(...)
<sales>
<rewrite>
<order>MyNamespace_MyModule_Model_Sales_Order</order>
</rewrite>
</sales>
</models>
(...)
</global>
Of course your own Sales_Order model should inherit from the core one. This is the cleanest way to override Magento core functionality (maybe besides events, but they can't do everything).
Create matching directories and files that you want modified in the local folder for the module. That should be all that is needed.
As mcmil correctly pointed out, create a module in your own namespace and extend from the core class. By doing this you are writing less code and creating less bloat. It also improves your upgrade path in the future.
If you simply copy the whole file from app/code/core to app/code/local and then the core file/class gets changed in the next Magento update you might miss out on those changes. If you are extending from the core class with your module then your new class will inherit those changes when you update Magento.
I am using the password confirmation validator from the official Zend framwork document here:
http://framework.zend.com/manual/en/zend.form.elements.html
In Bootstrap.php, I have set the namespace as
'namespace' => 'My_'
The file is located at
application/validate/PasswordConfirmation.php
However, "Fatal error: Class 'My_Validate_PasswordConfirmation' not found" occurs in my Zend_Form.
What should I do to fix the problem?
I designed and implemented Zend_Filter_Input, including its namespace feature.
You have a backwards understanding of how this feature works. It's meant to allow you to use a short name for a validator class when the actual name of that class is longer. You're apparently doing the reverse, trying to name a class with a longer name than it actually has.
To fix this I recommend the following steps:
Name the class My_Validate_PasswordConfirmation
Put it in `application/My/Validate/PasswordConfirmation.php
Add namespace=>'My_Validate' to your Zend_Filter_Input options.
Invoke the validator as simply "PasswordConfirmation".
update: I spent some time on this. It seems my first idea was off target. The namespace issue you have has nothing to do with the feature of Zend_Filter_Input, it has to do with the Zend_Application bootstrap feature. It seems that you can specify a class prefix to the autoloader.
Here's another clue:
Zend_Loader_Autoloader_Resource makes
the assumption that all code you are
autoloading will use an underscore
separator between namespaces,
components, and classes. As a result,
you do not need to use the trailing
underscore when registering a resource
autoloader.
So try this:
'namespace' => 'My',
with no trailing underscore.