1 bootstrap.inc backdrop_get_filename($type, $name, $filename = NULL)

Returns and optionally sets the filename for a system resource.

The filename, whether provided, cached, or retrieved from the database, is only returned if the file exists.

This function plays a key role in allowing Backdrop's resources (modules, layouts, and themes) to be located in different places depending on a site's configuration. For example, a module 'foo' may legally be located in any of these three places:

core/modules/foo/foo.module modules/foo/foo.module sites/example.com/modules/foo/foo.module

Calling backdrop_get_filename('module', 'foo') will give you one of the above, depending on where the module is located.


$type: The type of the item (theme, layout, theme_engine, module, profile).

$name: The name of the item for which the filename is requested.

$filename: The filename of the item if it is to be set explicitly rather than by consulting the database.

Return value

The filename of the requested item or NULL if the item is not found.:


core/includes/bootstrap.inc, line 1032
Functions that need to be loaded on every Backdrop request.


function backdrop_get_filename($type, $name, $filename = NULL) {
  // The location of files will not change during the request, so do not use
  // backdrop_static().
  static $files = array(), $dirs = array();

  // Profiles are a special case: they have a fixed location and naming.
  if ($type == 'profile') {
    $profile_filenames = array(
    foreach ($profile_filenames as $profile_filename) {
      if (file_exists($profile_filename)) {
        $files[$type][$name] = $profile_filename;
      else {
        $files[$type][$name] = FALSE;
  if (!isset($files[$type])) {
    $files[$type] = array();

  if (!empty($filename) && file_exists($filename)) {
    $files[$type][$name] = $filename;
  elseif (isset($files[$type][$name])) {
    // The file is in the database but does not exist on the disk.
  // Verify that we have an active database connection, before querying
  // the database. This is required because this function is called both
  // before we have a database connection (i.e. during installation) and
  // when a database connection fails.
  else {
    try {
      // Layouts we use the existing registry rather than the system table.
      if ($type === 'layout' && function_exists('layout_get_layout_template_info')) {
        $layout_info = layout_get_layout_template_info($name);
        if ($layout_info) {
          $files[$type][$name] = $layout_info['path'] . '/' . $layout_info['name'] . '.info';
      // Modules, themes, and profiles pull from the system table.
      elseif (function_exists('db_query')) {
        $file = db_query("SELECT filename FROM {system} WHERE name = :name AND type = :type", array(':name' => $name, ':type' => $type))->fetchField();
        if ($file && file_exists(BACKDROP_ROOT . '/' . $file)) {
          $files[$type][$name] = $file;
    catch (Exception $e) {
      // The database table may not exist because Backdrop is not yet installed,
      // or the database might be down. We have a fallback for this case so we
      // hide the error completely.

    // Fallback to searching the filesystem if the database could not find the
    // file or the file returned by the database is not found.
    if (!isset($files[$type][$name])) {
      // We have a consistent directory naming: modules, themes...
      $dir = $type . 's';
      if ($type == 'theme_engine') {
        $dir = 'themes/engines';
        $extension = 'engine';
      elseif ($type === 'theme' || $type === 'layout') {
        $extension = 'info';
      else {
        $extension = $type;

      if (!isset($dirs[$dir][$extension])) {
        $dirs[$dir][$extension] = TRUE;
        if (!function_exists('backdrop_system_listing')) {
          require_once BACKDROP_ROOT . '/core/includes/common.inc';
        // Scan the appropriate directories for all files with the requested
        // extension, not just the file we are currently looking for. This
        // prevents unnecessary scans from being repeated when this function is
        // called more than once in the same page request.
        $matches = backdrop_system_listing("/^" . BACKDROP_PHP_FUNCTION_PATTERN . "\.$extension$/", $dir, 'name', 0);
        foreach ($matches as $matched_name => $file) {
          $files[$type][$matched_name] = $file->uri;

  return isset($files[$type][$name]) ? $files[$type][$name] : NULL;