ai_upgrade_assistant-0.2.0-alpha2/src/Service/NodeVisitor/PluginVisitor.php

src/Service/NodeVisitor/PluginVisitor.php
<?php

namespace Drupal\ai_upgrade_assistant\Service\NodeVisitor;

use PhpParser\Node;
use PhpParser\NodeVisitorAbstract;

/**
 * Node visitor that analyzes plugin usage and deprecated plugin types.
 */
class PluginVisitor extends NodeVisitorAbstract {

  /**
   * List of findings.
   *
   * @var array
   */
  protected $findings = [];

  /**
   * List of deprecated plugin types and their replacements.
   *
   * @var array
   */
  protected $deprecatedPluginTypes = [
    'field.widget' => [
      'base_class' => 'Drupal\field\Plugin\Type\Widget\WidgetBase',
      'replacement' => 'Drupal\Core\Field\WidgetBase',
      'version' => '8.0.0',
      'critical' => true,
    ],
    'field.formatter' => [
      'base_class' => 'Drupal\field\Plugin\Type\Formatter\FormatterBase',
      'replacement' => 'Drupal\Core\Field\FormatterBase',
      'version' => '8.0.0',
      'critical' => true,
    ],
    'image.effect' => [
      'base_class' => 'Drupal\image\Plugin\ImageEffect\ImageEffectBase',
      'replacement' => 'Drupal\image\ImageEffectBase',
      'version' => '8.7.0',
      'critical' => false,
    ],
  ];

  /**
   * List of plugin types requiring special attention in Drupal 11.
   *
   * @var array
   */
  protected $drupal11PluginTypes = [
    'views.field' => [
      'changes' => [
        'New field value handling',
        'Enhanced render array support',
      ],
      'example' => 'Use structured render arrays for field output',
    ],
    'block' => [
      'changes' => [
        'Cache metadata improvements',
        'Block context handling',
      ],
      'example' => 'Use block context for dynamic content',
    ],
  ];

  /**
   * {@inheritdoc}
   */
  public function enterNode(Node $node) {
    if ($node instanceof Node\Stmt\Class_) {
      // Check for plugin annotation
      $doc_comment = $node->getDocComment();
      if ($doc_comment) {
        $finding = [
          'type' => 'plugin',
          'class' => $node->name->toString(),
          'line' => $node->getLine(),
          'file' => $node->getAttribute('file'),
        ];

        // Extract plugin type from annotation
        preg_match('/@(\w+)\(/', $doc_comment->getText(), $matches);
        if (!empty($matches[1])) {
          $finding['plugin_type'] = $matches[1];
        }

        // Check base classes
        if ($node->extends) {
          $base_class = $node->extends->toString();
          $finding['base_class'] = $base_class;

          // Check for deprecated base classes
          foreach ($this->deprecatedPluginTypes as $type => $info) {
            if ($base_class === $info['base_class']) {
              $finding['deprecated'] = true;
              $finding['replacement'] = $info['replacement'];
              $finding['version'] = $info['version'];
              $finding['critical'] = $info['critical'];
              break;
            }
          }
        }

        // Check for D11 plugin type changes
        if (isset($finding['plugin_type']) && isset($this->drupal11PluginTypes[$finding['plugin_type']])) {
          $finding['drupal11_changes'] = $this->drupal11PluginTypes[$finding['plugin_type']];
        }

        // Check plugin interfaces
        $interfaces = [];
        foreach ($node->implements as $interface) {
          $interfaces[] = $interface->toString();
        }
        if (!empty($interfaces)) {
          $finding['interfaces'] = $interfaces;
        }

        // Check plugin configuration
        foreach ($node->stmts as $stmt) {
          if ($stmt instanceof Node\Stmt\ClassMethod) {
            if ($stmt->name->toString() === 'defaultConfiguration') {
              $finding['has_configuration'] = true;
            }
            elseif ($stmt->name->toString() === 'buildConfigurationForm') {
              $finding['has_config_form'] = true;
            }
          }
        }

        $this->findings[] = $finding;
      }
    }
  }

  /**
   * Gets the findings.
   *
   * @return array
   *   Array of findings.
   */
  public function getFindings() {
    return $this->findings;
  }

  /**
   * Resets the findings.
   */
  public function reset() {
    $this->findings = [];
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc