You are here

function DrupalExtensionNamespaceFinderPlugin::findFile in X Autoload 7.5

Same name and namespace in other branches
  1. 7.4 lib/ClassFinder/Plugin/DrupalExtensionNamespaceFinderPlugin.php \Drupal\xautoload\ClassFinder\Plugin\DrupalExtensionNamespaceFinderPlugin::findFile()

Looks up a class starting with "Drupal\$extension_name\\".

This plugin method will be called for every class beginning with "Drupal\\$extension_name\\", as long as the plugin is registered for $logical_base_path = 'Drupal/$extension_name/'.

A similar plugin will is registered along with this one for the PEAR-FLAT pattern, called for every class beginning with $modulename . '_'.

The plugin will eventually unregister itself and its cousin, once it has

  • determined the correct path for the module, and
  • determined that the module is using either PSR-0 or PSR-4. It does that by including the file candidate for PSR-0 and/or PSR-4 and checking whether the class is now defined.

The plugin will instead register a direct

Parameters

\Drupal\xautoload\ClassFinder\InjectedApi\InjectedApiInterface $api: An object with methods like suggestFile() and guessFile().

string $logical_base_path: The logical base path determined from the registered namespace. E.g. 'Drupal/menupoly/'.

string $relative_path: Remaining part of the logical path following $logical_base_path. E.g. 'FooNamespace/BarClass.php'.

string|null $extension_name: Second key that the plugin was registered with. Usually this would be the physical base directory where we prepend the relative path to get the file path. But in this case it is simply the extensions name. E.g. 'menupoly'.

Return value

bool|null TRUE, if the file was found. FALSE or NULL, otherwise.

Overrides xautoload_FinderPlugin_Interface::findFile

1 method overrides DrupalExtensionNamespaceFinderPlugin::findFile()
DrupalExtensionUnderscoreFinderPlugin::findFile in src/ClassFinder/Plugin/DrupalExtensionUnderscoreFinderPlugin.php
Looks up a class starting with "Drupal\$extension_name\\".

File

src/ClassFinder/Plugin/DrupalExtensionNamespaceFinderPlugin.php, line 125

Class

DrupalExtensionNamespaceFinderPlugin
There are different dimensions of state for each module:

Namespace

Drupal\xautoload\ClassFinder\Plugin

Code

function findFile($api, $logical_base_path, $relative_path, $extension_name = NULL) {
  $extension_file = $this->system
    ->drupalGetFilename($this->type, $extension_name);
  if (empty($extension_file)) {

    // Extension does not exist, or is not installed.
    return FALSE;
  }
  $nspath = 'Drupal/' . $extension_name . '/';
  $testpath = $nspath . 'Tests/';
  $uspath = $extension_name . '/';
  $extension_dir = dirname($extension_file);
  $src = $extension_dir . '/src/';
  $lib_psr0 = $extension_dir . '/lib/Drupal/' . $extension_name . '/';
  $is_test_class = 0 === strpos($relative_path, 'Tests/');

  // Try PSR-4.
  if ($api
    ->guessPath($src . $relative_path)) {
    if ($is_test_class) {

      // Register PSR-0 directory for "Drupal\\$modulename\\Tests\\"
      // This generally happens only once per module, because for subsequent
      // test classes the class will be found before this plugin is triggered.
      // However, for class_exists() with nonexistent test files, this line
      // will occur more than once.
      $this->namespaceMap
        ->registerDeepPath($testpath, $src . 'Tests/', $this->defaultBehavior);

      // We found the class, but it is a test class, so it does not tell us
      // anything about whether non-test classes are in PSR-0 or PSR-4.
      return TRUE;
    }

    // Register PSR-4 directory for "Drupal\\$modulename\\".
    $this->namespaceMap
      ->registerDeepPath($nspath, $src, $this->defaultBehavior);

    // Unregister the lazy plugins, including this one, for
    // "Drupal\\$modulename\\" and for $modulename . '_'.
    $this->namespaceMap
      ->unregisterDeepPath($nspath, $extension_name);
    $this->prefixMap
      ->unregisterDeepPath($uspath, $extension_name);

    // Test classes in PSR-4 are already covered by the PSR-4 plugin we just
    // registered. But test classes in PSR-0 would slip through. So we check
    // if a separate behavior needs to be registered for those.
    if (is_dir($lib_psr0 . 'Tests/')) {
      $this->namespaceMap
        ->registerDeepPath($testpath, $lib_psr0 . 'Tests/', $this->psr0Behavior);
    }

    // The class was found, so return TRUE.
    return TRUE;
  }

  // Build PSR-0 relative path.
  if (FALSE === ($nspos = strrpos($relative_path, '/'))) {

    // No namespace separators in $relative_path, so all underscores must be
    // replaced.
    $relative_path = str_replace('_', '/', $relative_path);
  }
  else {

    // Replace only those underscores in $relative_path after the last
    // namespace separator, from right to left. On average there is no or very
    // few of them, so this loop rarely iterates even once.
    while ($nspos < ($uspos = strrpos($relative_path, '_'))) {
      $relative_path[$uspos] = '/';
    }
  }

  // Try PSR-0
  if ($api
    ->guessPath($lib_psr0 . $relative_path)) {
    if ($is_test_class) {

      // We know now that there are test classes using PSR-0.
      $this->namespaceMap
        ->registerDeepPath($testpath, $lib_psr0 . 'Tests/', $this->psr0Behavior);

      // We found the class, but it is a test class, so it does not tell us
      // anything about whether non-test classes are in PSR-0 or PSR-4.
      return TRUE;
    }

    // Unregister the lazy plugins, including this one.
    $this->namespaceMap
      ->unregisterDeepPath($nspath, $extension_name);
    $this->prefixMap
      ->unregisterDeepPath($uspath, $extension_name);

    // Register PSR-0 for regular namespaced classes.
    $this->namespaceMap
      ->registerDeepPath($nspath, $lib_psr0, $this->psr0Behavior);

    // Test classes in PSR-0 are already covered by the PSR-0 plugin we just
    // registered. But test classes in PSR-4 would slip through. So we check
    // if a separate behavior needs to be registered for those.

    # if (is_dir($src . 'Tests/')) {

    #   $this->namespaceMap->registerDeepPath($testpath, $src . 'Tests/', $this->psr0Behavior);

    # }

    // The class was found, so return TRUE.
    return TRUE;
  }
  return FALSE;
}