Loader::Find()

Added a method to the loader which can find all sub-classes /
implementations of a class / interface. The method must be called with
at least one argument (the name of the class / interface to find
subclasses / implementations of).

By default Loader::Find() will look for 'extra' classes. However, it is
possible to specify something else (e.g. 'ctrl' for controllers) as the
second argument.

Finally, by default, only packages which have already been loaded when
the method is called are considered. Passing false as the 3rd argument
will cause packages to be loaded.
This commit is contained in:
Emmanuel BENOîT 2012-02-07 09:22:25 +01:00
parent f1016b039f
commit 47b759d993

View file

@ -352,7 +352,11 @@ final class Loader
if ( empty( $args ) ) { if ( empty( $args ) ) {
$instance = new $cName(); $instance = new $cName();
} else { } else {
try {
$reflection = new ReflectionClass( $cName ); $reflection = new ReflectionClass( $cName );
} catch ( ReflectionException $e ) {
throw new LoaderException( "Class $cName from package $pName not found" );
}
$instance = $reflection->newInstanceArgs( $args ); $instance = $reflection->newInstanceArgs( $args );
} }
@ -391,6 +395,42 @@ final class Loader
return $instance; return $instance;
} }
public function findClasses( $class , $type = 'extra' , $onlyLoadedPackages = true )
{
$rType = $type . 's';
if ( ! array_key_exists( $rType , $this->items ) ) {
throw new LoaderException( "Invalid type '$type'" );
}
$convertName = ( $type !== 'extra' );
$result = array( );
foreach ( $this->items[ $rType ] as $item => $pName ) {
$cName = $convertName ? Loader::convertName( $type , $item ) : $item;
if ( ! strcasecmp( $cName , $class ) ) {
continue;
}
$package = $this->packages[ $pName ];
if ( ! $package->loaded( ) ) {
if ( $onlyLoadedPackages ) {
continue;
}
$this->loadPackage( $pName );
}
try {
$ref = new ReflectionClass( $cName );
} catch ( ReflectionException $e ) {
throw new LoaderException( "Class $cName for $item of type $type and package $pName not found" );
}
if ( $ref->implementsInterface( $class ) || $ref->isSubclassOf( $class ) ) {
$result[] = $item;
}
}
return $result;
}
private static function get( ) private static function get( )
{ {
@ -409,6 +449,7 @@ final class Loader
return $cName; return $cName;
} }
public static function DirectCreate( $type , $convert , $args ) public static function DirectCreate( $type , $convert , $args )
{ {
$name = array_shift( $args ); $name = array_shift( $args );
@ -488,4 +529,9 @@ final class Loader
{ {
return Loader::get( )->getDao( $name ); return Loader::get( )->getDao( $name );
} }
public static function Find( $class , $type = 'extra' , $onlyLoadedPackages = true )
{
return Loader::get( )->findClasses( $class , $type , $onlyLoadedPackages );
}
} }