You are here

private function LibraryDeprecationAnalyzer::analyzePhpLibraryReferences in Upgrade Status 8.3

Same name and namespace in other branches
  1. 8.2 src/LibraryDeprecationAnalyzer.php \Drupal\upgrade_status\LibraryDeprecationAnalyzer::analyzePhpLibraryReferences()

Analyzes libraries referenced in PHP.

This can only analyze statically attached libraries. We are not checking the context where the library is being referenced, so in some cases this could lead into false negatives. Testing the context would be possible, but could lead into not detecting all references to deprecated libraries.

Parameters

\Drupal\Core\Extension\Extension $extension:

Return value

\Drupal\upgrade_status\DeprecationMessage[]

1 call to LibraryDeprecationAnalyzer::analyzePhpLibraryReferences()
LibraryDeprecationAnalyzer::analyze in src/LibraryDeprecationAnalyzer.php
Analyzes usages of deprecated libraries in an extension.

File

src/LibraryDeprecationAnalyzer.php, line 324

Class

LibraryDeprecationAnalyzer
A library deprecation analyzer.

Namespace

Drupal\upgrade_status

Code

private function analyzePhpLibraryReferences(Extension $extension) : array {
  $iterator = new \RegexIterator(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($extension
    ->getPath()), \RecursiveIteratorIterator::LEAVES_ONLY), '/\\.(php|module|theme|profile|inc)$/');
  $deprecations = [];
  foreach ($iterator as $file) {
    try {
      $tokens = token_get_all(file_get_contents($file
        ->getPathName()));
    } catch (\ParseError $error) {

      // Ignore syntax errors.
      continue;
    }

    // Find nodes that look like attaching a library.
    $potential_libraries = array_values(array_map(function ($token) {
      list($type, $value, $line) = $token;
      return [
        'value' => substr($value, 1, -1),
        'line' => $line,
      ];
    }, array_filter($tokens, function ($token) {
      if (is_array($token)) {
        list($type, $value) = $token;
        return $type === T_CONSTANT_ENCAPSED_STRING && preg_match('/^[\\"\'][a-zA-Z0-9\\.\\-\\_]+\\/[a-zA-Z0-9\\.\\-\\_]+[\\"\']$/', $value);
      }
      return FALSE;
    })));
    foreach ($potential_libraries as $potential_library) {
      list($extension_name) = explode('/', $potential_library['value'], 2);
      $extension_lists = [
        $this->moduleExtensionList,
        $this->themeExtensionList,
        $this->profileExtensionList,
      ];

      // Iterate through all extension lists to see if we have found a valid
      // extension.
      $valid_extension = array_reduce($extension_lists, function ($valid_extension, ExtensionList $extension_list) use ($extension_name) {
        if ($valid_extension || $extension_list
          ->exists($extension_name)) {
          return TRUE;
        }
        return FALSE;
      }, FALSE);
      if ($valid_extension) {
        $is_deprecated = $this
          ->isLibraryDeprecated($potential_library['value']);
        if (is_null($is_deprecated)) {
          $message = sprintf("The '%s' library is not defined because the defining extension is not installed. Cannot decide if it is deprecated or not.", $potential_library['value']);
          $deprecations[] = new DeprecationMessage($message, $file
            ->getPathName(), $potential_library['line']);
        }
        elseif (!empty($is_deprecated)) {
          if ($is_deprecated instanceof DeprecationMessage) {
            $is_deprecated
              ->setFile($file
              ->getPathName());
            $deprecations[] = $is_deprecated;
          }
          else {
            $message = "The referenced library is deprecated. {$is_deprecated}";
            $deprecations[] = new DeprecationMessage($message, $file
              ->getPathName(), $potential_library['line']);
          }
        }
      }
    }
  }
  return $deprecations;
}