Custom Configuration trouble

Hi all!

After spending hours on my problem without any solution, I hope anyone can help.
The task is very easy and I did it several times in other flow projects:
reading informations from custom yaml.

I’ve done like other times: placing a file named “Package.php” into
Packages/Application/MY.project/Classes/MY/project/

It contains following code:

<?php namespace MY\project; use TYPO3\Flow\Annotations as Flow; use TYPO3\Flow\Package\Package as BasePackage; use TYPO3\Flow\Configuration\ConfigurationManager; use \TYPO3\Flow\Core\Bootstrap; /** * Class Package * * @package MY\project */ class Package extends BasePackage{ /** * @Flow\Inject * @var \TYPO3\Flow\Package\PackageManagerInterface */ protected $packageManager; /** * * @param \TYPO3\Flow\Core\Bootstrap $bootstrap The current bootstrap * @return void */ public function boot(\TYPO3\Flow\Core\Bootstrap $bootstrap) { $dispatcher = $bootstrap->getSignalSlotDispatcher(); $dispatcher->connect('TYPO3\Flow\Configuration\ConfigurationManager', 'configurationManagerReady', function ($configurationManager) { $configurationManager->registerConfigurationType('bla',ConfigurationManager::CONFIGURATION_PROCESSING_TYPE_DEFAULT,TRUE); } ); } // public function boot } // class Package If I place this in one of my classes: /** * * @Flow\InjectConfiguration(type="bla") * @var array */ protected $blaSettings = array(); I get an Exception like this: Exception #1420736211 in line 156 of Packages/Framework/TYPO3.Flow/Classes/TYPO3/Flow/Object/DependencyInjection/ProxyClassBuilder.php: The configuration injection specified for property "blaSettings" in the object configuration of object "MY\project\ClassXYZ" refers to the unknown configuration type "bla". I have double checked every spelling, location of "Package.php" and so on. I have compared my code of this project with working reference projects: all is matching! I have checked and compared the code generated in Cache/Code/Flow_Object_Classes/MY_project_Package.php : seem to be ok and looks like ref. project. Finally I've placed a die('Stopped here'); into Package->boot(...) as first line and excute from command line ./flow configuration:show all confs are showed except "bla". I did the same in my reference project: "die" is executed (and no confs are schown). For some reasons **it seems Package->boot(...) of my project is NOT called**. Note: - if I place a syntax error in this methode an appropriate exception is thrown. - if I place a typo in namespace I get an reflection error (as expected). For now I don't have an idea what is going wrong here! What can I check furthermore? As allways. every hint welcome! P.S.: I'm using FLOW 3.3

Hello Frank,

did you run ./flow flow:package:rescan … maybe flow does not know about your package.php yet.

Maybe a stupid question … why do you use a special configuration and not just Settings.yaml. You can easyly get your Settings in all your package classes with the Flow\InjectConfiguration configuration. See: http://flowframework.readthedocs.io/en/3.3/TheDefinitiveGuide/PartIII/Configuration.html#accessing-settings

Regards Martin

Hello Martin!

YES, ./flow flow:package:rescan did the job!
Thank you very much!
Strange, I’ve believed, if MY_project_Package.php exists in Object-Cache the framework knows about this class…
In fact I tried “rescan” - but in wrong syntax. But in my wrong assumption about MY_project_Package.php, I havn’t done further investigations :frowning:

Also strange: I’ve never used “rescan” before and all worked fine …

And: yes I know about settings, but by exclude special defintions from settings, customization is more documenting.

Thanx again
Frank

1 Like

We have a couple of constraints regarding Package.php files which either mean using package:rescan or loosing quite a bit of performance. They need to work before proxies are created AND we need to load th classes. So to do that we basically need to know very early if a package has a Package.php and what namespace it has. In earlier versions we scanned all packages for the class which is pretty time consuming. Now we rely on a cached state that is refreshed via package:rescan.

Couldn’t we use the file monitor to tackle this at least in Development context? This one has bitten quite some people already

If you know a way that doesn’t bust performance… I don’t see it because without knowledge of the fully qualified class name and the autoloading type of the package we cannot know where a package file is even supposed to be for a given package. That’s what makes it so hard.

Didn’t really test it and it probably needs some recursion detection, but sth. along those lines could work:

diff --git a/Neos.Flow/Classes/Core/Booting/Scripts.php b/Neos.Flow/Classes/Core/Booting/Scripts.php
index 1b46708..deb0d0c 100644
--- a/Neos.Flow/Classes/Core/Booting/Scripts.php
+++ b/Neos.Flow/Classes/Core/Booting/Scripts.php
@@ -482,7 +482,8 @@ class Scripts
         $fileMonitors = [
             'Flow_ClassFiles' => FileMonitor::createFileMonitorAtBoot('Flow_ClassFiles', $bootstrap),
             'Flow_ConfigurationFiles' => FileMonitor::createFileMonitorAtBoot('Flow_ConfigurationFiles', $bootstrap),
-            'Flow_TranslationFiles' => FileMonitor::createFileMonitorAtBoot('Flow_TranslationFiles', $bootstrap)
+            'Flow_TranslationFiles' => FileMonitor::createFileMonitorAtBoot('Flow_TranslationFiles', $bootstrap),
+            'Flow_PackageFiles' => FileMonitor::createFileMonitorAtBoot('Flow_PackageFiles', $bootstrap),
         ];
 
         $context = $bootstrap->getContext();
@@ -504,6 +505,7 @@ class Scripts
             }
             foreach ($package->getAutoloadPaths() as $autoloadPath) {
                 self::monitorDirectoryIfItExists($fileMonitors['Flow_ClassFiles'], $autoloadPath, '\.php$');
+                self::monitorDirectoryIfItExists($fileMonitors['Flow_PackageFiles'], $autoloadPath, '^Package\.php$');
             }
 
             if ($context->isTesting() && $package instanceof Package) {
diff --git a/Neos.Flow/Classes/Package.php b/Neos.Flow/Classes/Package.php
index d86d71d..4c6b191 100644
--- a/Neos.Flow/Classes/Package.php
+++ b/Neos.Flow/Classes/Package.php
@@ -11,6 +11,7 @@ namespace Neos\Flow;
  * source code.
  */
 
+use Neos\Flow\Monitor\ChangeDetectionStrategy\ChangeDetectionStrategyInterface;
 use Neos\Flow\Package\Package as BasePackage;
 use Neos\Flow\ResourceManagement\ResourceManager;
 
@@ -105,6 +106,18 @@ class Package extends BasePackage
         });
 
         $dispatcher->connect(\Neos\Flow\Monitor\FileMonitor::class, 'filesHaveChanged', \Neos\Flow\Cache\CacheManager::class, 'flushSystemCachesByChangedFiles');
+        $dispatcher->connect(\Neos\Flow\Monitor\FileMonitor::class, 'filesHaveChanged', function($fileMonitorIdentifier, array $changedFiles) use ($bootstrap) {
+            if ($fileMonitorIdentifier !== 'Flow_PackageFiles') {
+                return;
+            }
+            foreach ($changedFiles as $changedFile => $status) {
+                if ($status === ChangeDetectionStrategyInterface::STATUS_CREATED || $status === ChangeDetectionStrategyInterface::STATUS_DELETED) {
+                    $packageManager = $bootstrap->getEarlyInstance(\Neos\Flow\Package\PackageManagerInterface::class);
+                    $packageManager->rescanPackages();
+                    return;
+                }
+            }
+        });
 
         $dispatcher->connect(\Neos\Flow\Tests\FunctionalTestCase::class, 'functionalTestTearDown', \Neos\Flow\Mvc\Routing\RouterCachingService::class, 'flushCaches');