RobLoach / class-loader-adapter

Common interface to interact with a number of different class loaders.
Other
1 stars 1 forks source link

UniversalClassLoader support #4

Open donquixote opened 11 years ago

donquixote commented 11 years ago

Hi, if you really want to mimick the more "modern" loaders with UniversalClassLoaders, then in certain cases you might have to register namespace AND prefix.

The following is from the current version of the Krautoload RegistrationHub, which attempts the same thing, and still does not simulate all possible "false positives". The question is, is this even intended?

  function composerPrefix($prefix, $paths) {

    if (!$prefix) {
      // We consider this as a "fallback".
    }
    elseif ('\\' === substr($prefix, -1)) {
      // We assume that $prefix is meant as a namespace,
      // and the paths are PSR-0 directories.
      $namespace = substr($prefix, 0, -1);
      foreach ((array) $paths as $path) {
        $this->namespacePSR0($namespace, $path);
      }
    }
    elseif (FALSE !== strrpos($prefix, '\\')) {
      // We assume that $prefix is meant as a namespace,
      // and the paths are PSR-0 directories.
      $namespace = $prefix;
      foreach ((array) $paths as $path) {
        $this->namespacePSR0($namespace, $path);
        $this->classFile($prefix, $path . '.php');
      }
      // TODO:
      //   Register special plugins to cover other FQCNs
      //   that happen to begin with with the prefix.
    }
    elseif ('_' === substr($prefix, -1)) {
      // We assume that $prefix is meant as a PEAR prefix,
      // and the paths are PSR-0 directories.
      foreach ((array) $paths as $path) {
        $this->prefixPEAR(substr($prefix, 0, -1), $path);
      }
      // TODO:
      //   Register special plugins to cover other FQCNs
      //   that happen to begin with with the prefix.
    }
    else {
      // We assume that $prefix is meant as a PEAR prefix OR as namespace,
      // and the paths are PSR-0 or PEAR directories.
      foreach ((array) $paths as $path) {
        $this->namespacePSR0($prefix, $path);
        $this->prefixPEAR($prefix, $path);
        $this->classFile($prefix, $path . '.php');
      }
      // TODO:
      //   Register special plugins to cover other FQCNs
      //   that happen to begin with with the prefix.
    }
  }

Examples:

$loader = new \Symfony\Component\ClassLoader\ClassLoader:

$loader->addPrefix('Gira', 'src');
$loader->findFile('Gira\\Foo') ==> 'src/Gira/Foo.php'
$loader->findFile('Gira_Foo') ==> 'src/Gira/Foo.php'
$loader->findFile('Giraffe\\Foo') ==> 'src/Giraffe/Foo.php'
$loader->findFile('Giraffe_Foo') ==> 'src/Giraffe/Foo.php'

$loader->addPrefix('Base_', 'lib');
$loader->findFile('Base_Foo') ==> 'lib/Base/Foo.php'
$loader->findFile('Base_\\Foo') ==> 'lib/Base_/Foo.php'
$loader->findFile('Base_Foo_Bar') ==> 'lib/Base/Foo/Bar.php'
$loader->findFile('Base_Foo\\Bar') ==> 'lib/Base_Foo/Bar.php'
RobLoach commented 11 years ago

You don't mean Symfony's UniversalClassLoader, do you? https://github.com/RobLoach/class-loader-adapter/blob/master/src/RobLoach/ClassLoaderAdapter/Symfony/UniversalClassLoader.php

Most of that code is taken from what Drupal had before the switch to ClassLoader. UniversalClassLoader is rather old and is rather deprecated by ClassLoader.

This package is not aimed to implement its own class loader, but rather provide interoperability between a bunch of third-party ones. Is this what you were getting at? Or are you suggesting to add more functionality to support outside the scope of PSR-0?

addPrefix() is aimed to just target PSR-0 namespaces. PSR-0 namespace loading can cover PEAR-like namespaces. You can see that covered in the test coverage here: https://github.com/RobLoach/class-loader-adapter/blob/master/tests/RobLoach/ClassLoaderAdapter/Test/ClassLoaderAdapterTest.php#L62 http://github.com/RobLoach/class-loader-adapter/tree/master/tests/RobLoach/ClassLoaderAdapter/Test/Fixtures