1 common.inc backdrop_system_listing($mask, $directory, $key = 'name', $min_depth = 1)

Returns information about system object files (modules, themes, etc.).

This function is used to find all or some system object files (module files, theme files, etc.) that exist on the site. It searches in several locations, depending on what type of object you are looking for. For instance, if you are looking for modules and call:

backdrop_system_listing("/\.module$/", "modules", 'name', 0);

The following directories will then be searched for modules:

  • /sites/[site_name]/modules
  • /modules
  • /profiles/[install_profile_name]/modules
  • /core/profiles/[install_profile_name]/modules
  • /core/modules

Directories will be searched in that order. If a module of the same name exists in two places, the earlier locations will take precedence over the later ones.

The information is returned in an associative array, which can be keyed on the file name ($key = 'filename'), the file name without the extension ($key = 'name'), or the full file stream URI ($key = 'uri'). If you use a key of 'filename' or 'name', files found later in the search will take precedence over files found earlier (unless they belong to a module or theme not compatible with Backdrop core); if you choose a key of 'uri', you will get all files found.

Parameters

string $mask: The preg_match() regular expression for the files to find.

string $directory: The subdirectory name in which the files are found. For example, 'modules' will search in sub-directories of the /core/modules/ directory, sub-directories of /modules/, etc.

string $key: The key to be used for the associative array returned. Possible values are 'uri', for the file's URI; 'filename', for the basename of the file; and 'name' for the name of the file without the extension. If you choose 'name' or 'filename', only the highest-precedence file will be returned.

int $min_depth: Minimum depth of directories to return files from, relative to each directory searched. For instance, a minimum depth of 2 would find modules inside /core/modules/node/tests, but not modules directly in /core/modules/node.

Return value

array: An associative array of file objects, keyed on the chosen key. Each element in the array is an object containing file information, with properties:

  • 'uri': Full URI of the file.
  • 'filename': File name.
  • 'name': Name of file without the extension.

File

core/includes/common.inc, line 6131
Common functions that many Backdrop modules will need to reference.

Code

function backdrop_system_listing($mask, $directory, $key = 'name', $min_depth = 1) {
  $config = conf_path();
  $files = array();

  // Search for the directory in core.
  $searchdir = array('core/' . $directory);

  // For the case of searching for profiles, scan top-level directories.
  // Always search for contributed and custom extensions in the profile
  // directories as well as in the root directories. If the same extension is
  // located in both directories, then the latter wins for legacy/historical
  // reasons.
  $profiles = array();
  $profile = backdrop_get_profile();
  // For SimpleTest to be able to test modules packaged together with a
  // distribution we need to include the profile of the parent site (in which
  // test runs are triggered).
  if (backdrop_valid_test_ua()) {
    $testing_profile = config_get('simpletest.settings', 'simpletest_parent_profile');
    if ($testing_profile && $testing_profile != $profile) {
      $profiles[] = $testing_profile;
    }
  }
  // In case both profile directories contain the same extension, the actual
  // profile always has precedence.
  $profiles[] = $profile;
  foreach ($profiles as $profile) {
    if (file_exists("core/profiles/$profile/$directory")) {
      $searchdir[] = "core/profiles/$profile/$directory";
    }
    if (file_exists("profiles/$profile/$directory")) {
      $searchdir[] = "profiles/$profile/$directory";
    }
  }

  $searchdir[] = $directory;
  if ($config !== '.' && file_exists("$config/$directory")) {
    $searchdir[] = "$config/$directory";
  }

  // Do not check for system files in common special-purpose directories.
  $ignore_directories = array(
    'assets',
    'css',
    'scss',
    'less',
    'js',
    'images',
    'templates',
    'node_modules',
    'bower_components',
  );
  $no_mask = '/^((\..*)|' . implode('|', $ignore_directories) . ')$/';

  // Get current list of items.
  if (!function_exists('file_scan_directory')) {
    require_once BACKDROP_ROOT . '/core/includes/file.inc';
  }
  foreach ($searchdir as $dir) {
    $files_to_add = file_scan_directory($dir, $mask, array('key' => $key, 'min_depth' => $min_depth, 'nomask' => $no_mask));

    // Duplicate files found in later search directories take precedence over
    // earlier ones, so we want them to overwrite keys in our resulting
    // $files array.
    // The exception to this is if the later file is from a module or theme not
    // compatible with Backdrop core. This may occur during upgrades of Backdrop
    // core when new modules exist in core while older contrib modules with the
    // same name exist in a directory such as /modules.
    foreach (array_intersect_key($files_to_add, $files) as $file_key => $file) {
      // If it has no info file, then we just behave liberally and accept the
      // new resource on the list for merging.
      if (file_exists($info_file = dirname($file->uri) . '/' . $file->name . '.info')) {
        // Get the .info file for the module or theme this file belongs to.
        $info = backdrop_parse_info_file($info_file);

        // If the module or theme is incompatible with Backdrop core, remove it
        // from the array for the current search directory, so it is not
        // overwritten when merged with the $files array.
        if (isset($info['backdrop']) && $info['backdrop'] != BACKDROP_CORE_COMPATIBILITY) {
          unset($files_to_add[$file_key]);
        }
      }
    }
    $files = array_merge($files, $files_to_add);
  }

  return $files;
}