Drupal 8 is going PSR-4. Yeah!
X Autoload will follow.

Along with that, we will try to make X Autoload more similar to the Composer autoloader, but not necessarily identical.

Comments

donquixote’s picture

One obstacle on the way to PSR-4:
The entire plugin architecture is standing in the way.

By default, xautoload will do the PSR-0 style substitution of namespace separators and underscores.
So, Drupal\some_mod\Sub_Sub\Foo_Bar is transformed into the logical path Drupal/some_mod/Sub_Sub/Foo/Bar.php.
For PSR-4, we need a slightly different transformation, where the logical path will be Drupal/some_mod/Sub_Sub/Foo_Bar.php, so the last underscore is not replaced.

With xautoload, we can simply register a FinderPlugin that will do this custom transformation. I already have a local branch where this is working nicely.

However: For module namespace we do not simply register the PSR-0 mappings, but we also register a "MissingDirPlugin". If a module-provided class is not found in the subscribed PSR-0 directory, xautoload will check if the subscribed directory does exist at all, and if it does not, it will ask the MissingDirPlugin subscribed for the logical base path whether the directory might have moved to a different location. This could happen if e.g. the module was moved into the /contrib/ folder, or from /contrib/ to /custom/ or elsewhere.

This does sound crazy, and I would be willing to give up on this mechanic, if we have a test to verify that things are still going to work ok. Atm I am quite sure that our tests do not cover all those scenarios.

Unfortunately, if we use a FinderPlugin for PSR-4, then we can not at the same time use a MissingDirPlugin. We could instead add some missing directory behavior into the FinderPlugin. However, we still need tests to verify if this is working, or if this is even necessary.

One problem with the tests is that they are slow. It would be great if we could simulate the relevant boot scenarios with phpunit instead.

donquixote’s picture

This is getting close - yeah!
But, there is one problem: Drupal 8 has not ultimately decided yet whether the default PSR-4 folder should be "src" or "lib".

If I decide to support either of these as a default in xautoload, and then it turns out I am wrong, then in the end I need to support both as a default. Forever, to avoid BC break.

I think the better solution might be to require an explicit input from the module to enable PSR-4 and to tell xautoload whether it should be src or lib. Then even if the default is going to be something other than that, the module will still work.

The question is, how should this "explicit input" look like?
Some criteria:
- easy to write.
- easy to copy, ideally not even containing the module name.
- available as early as possible.
- It should override the regular detection of psr-0 vs pear-flat (vs psr-4).
- In the future it will become redundant, as PSR-4 will be registered by default, but it will not be absolutely required to delete the line.

E.g. in the MODULE.module file:

// This will automatically determine the module name and module directory.
xautoload()->registerModulePsr4(__FILE__, 'src');

Or better via hook_xautoload() ?

function MODULE_xautoload($api) {
  $api->addPsr4('Drupal\MODULE\', 'src');
  // or what about
  $api->addModulePsr4('src');
}

I would like to find a syntax that will stick around and that we don't

indytechcook’s picture

IMO the hook implementation is more "Drupal" and will probably be more adapted.

It would also be easier to document in an xautoload.api.php.

donquixote’s picture

donquixote’s picture

Issue summary: View changes
Status: Active » Closed (fixed)

This is resolved now.

- The recommended way to register non-standard namespace paths is to use hook_xautoload().
- The recommended variable name for the $api object is now $adapter.
- Methods on this adapter object resemble those from Composer, but there are more for convenience.
- In 7.x-5.x, PSR-4 in "src" is registered automatically.