owncloud/core — pull request #6628 by AdamWill (2014-01-04 03:43:22+00:00)
Title: revise autoloader for non-OC classes to be PSR-0 compliant and more robust

The existing design of the autoloader is based around the particular needs of OC classes and doesn't work very well for vendor classes that OC bundles but which may be un-bundled by distributors. This almost splits the autoloader in two. It acts as before for OC classes (starting with OC or Test). For all other classes, there is a new function (findVendorClass) which simply returns the PSR-0 style class path, and the load function now acts much like a typical PSR-0ish autoloader. First it tries pre-pending the registered prefix for the class - if there is one - to the class path and resolving the result via stream_resolve_include_path. If that doesn't work, it falls back to just trying the class path, which will find any distributor copies stored in PSR-0 compliant locations relative to the include path.

As written, this implementation is an 'aggressive' one, it will run whenever a class is not found and the fallback function may find a systemwide copy of the class. If we would prefer a more conservative autoloader which only tries to load registered classes, it would be pretty simple to adjust this implementation to do that.

If we take the 'aggressive' approach we can drop all the prefix registrations in base.php which just register the prefix with the directory '3rdparty', as 3rdparty is already added to the include path in base.php and this autoloader should therefore find anything which is PSR-0 compliant wrt 3rdparty/ just fine.

As submitted this will fail some of the tests. Obviously they'd need to be adjusted to use findVendorClass in the appropriate tests rather than findClass, but that alone isn't enough, because the tests assume the 'class finding' function returns a prefixed but not completely resolved path, which is kind of what this patch is trying to avoid, because we want to handle both prefixed and non-prefixed possibilities. It's easy to move the prefix handling stuff into findVendorClass if we like it better that way, but findVendorClass has to return *either* just the classpath *or* the tested-and-fully resolved path. I don't see a way to make this approach work with the current testing approach. Obviously we can re-design the tests, but I didn't want to put the work into doing that unless the approach is approved, or else it'd be wasted.

I have tested myself that this works for all obvious cases, in my test Fedora 20 / OwnCloud 6.0.0a instance with this autoloader code. It correctly finds OC's bundled Patchwork (which uses namespaces), OC's bundled Sabre_DAV classes (which use old-skool underscores and a prefix registered in base.php), Fedora's unbundled Symfony (which uses namespaces) in the system PHP dirs, and Fedora's unbundled copy of php-dropbox (which uses underscores) if I comment out the 'requires_once' lines in the dropbox files (magic autoloading!).

I expect the tests PrefixNamespace and Prefix would fail. findVendorClass would return Foo/Bar.php in both cases.