lithium\core\Libraries::locate()
Performs service location for an object of a specific type. If $name
is a string, finds the
first instance of a class with the given name in any registered library (i.e. apps, plugins
or vendor libraries registered via Libraries::add()
), based on each library's order of
precedence. For example, this will find the first model called File
in any plugin or class
library loaded into an application, including the application itself.
Libraries::locate('models', 'File');
Order of precedence is usually based on the order in which the library was registered (via
Libraries::add()
), unless the library was registered with the 'defer'
option set to
true
. All libraries with the 'defer'
option set will be searched in
registration-order after searching all libraries without 'defer'
set. This means
that in the above example, if an app and a plugin both have a model named File
, then the
model from the app will be returned first, assuming the app was registered first (and
assuming the default settings).
If $name
is not specified, locate()
returns an array with all classes of the specified
type which can be found. By default, locate()
searches all registered libraries.
Libraries::locate('models');
For example, the above will return an array of all model classes in all registered plugins and libraries (including the app itself).
To learn more about adding and modifying the class paths used with locate()
, see the
documentation for the paths()
method.
Parameters
-
string
$type
The type of class to search for. Typically follows the name of the directory in which the class is stored, i.e.
'models'
,'controllers'
or'adapter'
. Some classes types, such as adapters, will require a greater degree of specificity when looking up the desired class. In this case, the dot syntax is used, as in this example when looking up cache adapters:'adapter.storage.cache'
, or this example, when looking up authentication adapters:'adapter.security.auth'
. -
string
$name
The base name (without namespace) of the class you wish to locate. If unspecified,
locate()
will attempt to find all classes of the type specified in$type
. If you only wish to search for classes within a single plugin or library, you may use the dot syntax to prefix the class name with the library name, i.e.'app.Post'
, which will only look for aPost
model within the app itself. -
array
$options
The options to use when searching and returning class names.
'type'
string: Defaults to'class'
. If set to'file'
, returns file names instead of class names.'library'
string: When specified, only the given library/plugin name will be searched.
Returns
mixedIf $name
is specified, returns the name of the first class found that matches
$name
and $type
, or returns null
if no matching classes were found in any
registered library. If $name
is not specified, returns an array of all classes
found which match $type
.
Source
public static function locate($type, $name = null, array $options = []) {
if (is_object($name) || is_string($name) && strpos($name, '\\') !== false) {
return $name;
}
$ident = $name ? ($type . '.' . $name) : ($type . '.*');
$ident .= $options ? '.' . md5(serialize($options)) : null;
if (isset(static::$_cachedPaths[$ident])) {
return static::$_cachedPaths[$ident];
}
$params = static::_params($type, $name);
$defaults = [
'type' => 'class',
'library' => $params['library'] !== '*' ? $params['library'] : null
];
$options += $defaults;
unset($params['library']);
$paths = static::paths($params['type']);
if (!isset($paths)) {
return null;
}
if ($params['name'] === '*') {
$result = static::_locateAll($params, $options);
return (static::$_cachedPaths[$ident] = $result);
}
if ($options['library']) {
$result = static::_locateDeferred(null, $paths, $params, $options);
return static::$_cachedPaths[$ident] = $result;
}
foreach ([false, true] as $defer) {
if ($result = static::_locateDeferred($defer, $paths, $params, $options)) {
return (static::$_cachedPaths[$ident] = $result);
}
}
}