ai_upgrade_assistant-0.2.0-alpha2/src/Controller/ReportController.php

src/Controller/ReportController.php
<?php

namespace Drupal\ai_upgrade_assistant\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Extension\ModuleExtensionList;
use Drupal\Core\State\StateInterface;
use Drupal\Core\Url;
use Drupal\ai_upgrade_assistant\Service\HuggingFaceService;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Controller for the AI Upgrade Assistant reports.
 */
class ReportController extends ControllerBase {

  /**
   * The module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * The module extension list.
   *
   * @var \Drupal\Core\Extension\ModuleExtensionList
   */
  protected $moduleList;

  /**
   * The HuggingFace service.
   *
   * @var \Drupal\ai_upgrade_assistant\Service\HuggingFaceService
   */
  protected $huggingFace;

  /**
   * The state service.
   *
   * @var \Drupal\Core\State\StateInterface
   */
  protected $state;

  /**
   * Constructs a new ReportController.
   *
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   * @param \Drupal\Core\Extension\ModuleExtensionList $module_list
   *   The module extension list.
   * @param \Drupal\ai_upgrade_assistant\Service\HuggingFaceService $huggingFace
   *   The HuggingFace service.
   * @param \Drupal\Core\State\StateInterface $state
   *   The state service.
   */
  public function __construct(
    ModuleHandlerInterface $module_handler,
    ModuleExtensionList $module_list,
    HuggingFaceService $huggingFace,
    StateInterface $state
  ) {
    $this->moduleHandler = $module_handler;
    $this->moduleList = $module_list;
    $this->huggingFace = $huggingFace;
    $this->state = $state;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('module_handler'),
      $container->get('extension.list.module'),
      $container->get('ai_upgrade_assistant.huggingface'),
      $container->get('state')
    );
  }

  /**
   * Displays the overview page.
   */
  public function overview() {
    // Get results from state
    $projects = $this->state->get('upgrade_status.project_summary', []);
    
    $rows = [];
    foreach ($projects as $project) {
      if (empty($project['paths'])) {
        continue;
      }

      $status = $this->t('Not analyzed');
      if (!empty($project['data'])) {
        $errors = $project['data']['totals']['errors'] ?? 0;
        $warnings = $project['data']['totals']['warnings'] ?? 0;
        $status = $this->t('@errors errors, @warnings warnings', [
          '@errors' => $errors,
          '@warnings' => $warnings,
        ]);
      }

      $ai_status = '';
      $ai_results = $this->state->get('ai_upgrade_assistant.analysis_results.' . $project['name'], []);
      if (!empty($ai_results)) {
        $ai_status = $this->t('AI analysis available');
      }

      $rows[] = [
        $project['name'],
        $project['type'],
        $status,
        $ai_status,
        [
          'data' => [
            '#type' => 'operations',
            '#links' => [
              'analyze' => [
                'title' => $this->t('Get AI recommendations'),
                'url' => Url::fromRoute('ai_upgrade_assistant.analyze', ['module' => $project['name']]),
              ],
            ],
          ],
        ],
      ];
    }

    $build['table'] = [
      '#type' => 'table',
      '#header' => [
        $this->t('Name'),
        $this->t('Type'),
        $this->t('Status'),
        $this->t('AI Analysis'),
        $this->t('Operations'),
      ],
      '#rows' => $rows,
      '#empty' => $this->t('No modules found.'),
    ];

    return $build;
  }

  /**
   * Analyzes a specific module with AI assistance.
   *
   * @param string $module
   *   The module to analyze.
   */
  public function analyze($module) {
    $batch = [
      'operations' => [
        [
          [$this, 'processAiAnalysis'],
          [$module],
        ],
      ],
      'finished' => [$this, 'finishAiAnalysis'],
      'title' => $this->t('Analyzing @module with AI assistance', ['@module' => $module]),
      'progress_message' => $this->t('Analyzing files...'),
      'error_message' => $this->t('An error occurred during analysis.'),
    ];

    batch_set($batch);
    return batch_process(Url::fromRoute('ai_upgrade_assistant.report'));
  }

  /**
   * Batch operation to process AI analysis.
   */
  public function processAiAnalysis($module, &$context) {
    if (!isset($context['sandbox']['progress'])) {
      $context['sandbox']['progress'] = 0;
      $context['sandbox']['current_id'] = 0;
      $context['results'] = [];
      
      // Get Upgrade Status results from state
      $project = $this->state->get('upgrade_status.scan_results.' . $module, NULL);
      
      if (!$project || empty($project['data'])) {
        throw new \Exception('No Upgrade Status data available. Please run Upgrade Status scan first.');
      }
      
      $context['sandbox']['files'] = [];
      foreach ($project['data']['files'] ?? [] as $file => $issues) {
        if (!empty($issues)) {
          $context['sandbox']['files'][] = [
            'file' => $file,
            'issues' => $issues,
          ];
        }
      }
      
      $context['sandbox']['max'] = count($context['sandbox']['files']);
    }

    // Process one file at a time
    if (!empty($context['sandbox']['files'])) {
      $file_data = array_shift($context['sandbox']['files']);
      $file = $file_data['file'];
      $issues = $file_data['issues'];
      
      try {
        // Get file contents
        $module_path = $this->moduleHandler->getModule($module)->getPath();
        $file_path = $module_path . '/' . $file;
        
        if (file_exists($file_path)) {
          $code = file_get_contents($file_path);
          
          // Get AI recommendations
          $ai_analysis = $this->huggingFace->analyzeCode($code, [
            'module' => $module,
            'file' => $file,
            'issues' => $issues,
            'drupal_version' => \Drupal::VERSION,
          ]);
          
          $context['results']['files'][$file] = [
            'issues' => $issues,
            'ai_recommendations' => $ai_analysis,
          ];
        }
      }
      catch (\Exception $e) {
        $context['results']['errors'][] = $e->getMessage();
      }
      
      $context['sandbox']['progress']++;
      $context['message'] = $this->t('Analyzing file @file...', ['@file' => $file]);
    }

    if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
      $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
    }
  }

  /**
   * Batch finish callback.
   */
  public function finishAiAnalysis($success, $results, $operations) {
    if ($success) {
      if (!empty($results['errors'])) {
        foreach ($results['errors'] as $error) {
          $this->messenger()->addError($error);
        }
      }
      
      if (!empty($results['files'])) {
        $this->messenger()->addStatus($this->t('AI analysis completed. Found recommendations for @count files.', [
          '@count' => count($results['files']),
        ]));
      }
      
      // Store results
      $this->state->set('ai_upgrade_assistant.analysis_results.' . $operations[0][1][0], $results);
    }
    else {
      $this->messenger()->addError($this->t('An error occurred during analysis.'));
    }
  }

  /**
   * Generates a comprehensive upgrade report.
   *
   * @return array
   *   A render array for the report page.
   */
  public function generateReport() {
    try {
      $modules = $this->moduleList->getList();
      $report_data = [];

      // Get scan results from state
      $scan_results = $this->state->get('upgrade_status.project_summary', []);

      foreach ($modules as $name => $extension) {
        // Skip core modules
        if (strpos($name, 'core') === 0) {
          continue;
        }

        // Get scan results for this module
        $module_scan_results = $this->state->get("upgrade_status.scan_results.$name", []);
        if (!$module_scan_results) {
          continue;
        }

        // Get deprecations from scan results
        $deprecations = $module_scan_results['data']['files'] ?? [];

        // Get AI analysis
        $ai_analysis = $this->state->get("ai_upgrade_assistant.analysis_results.$name", []);

        // Combine the results
        $report_data[$name] = [
          'name' => $name,
          'type' => $extension->getType(),
          'version' => $extension->info['version'] ?? 'Unknown',
          'deprecations' => $deprecations,
          'ai_analysis' => $ai_analysis,
          'scan_results' => $module_scan_results,
          'summary' => $scan_results[$name] ?? [],
        ];
      }

      // Build the page
      return [
        '#theme' => 'analysis_report',
        '#report_data' => $report_data,
        '#attached' => [
          'library' => ['ai_upgrade_assistant/analysis_report'],
        ],
      ];
    }
    catch (\Exception $e) {
      $this->logger('ai_upgrade_assistant')->error('Error generating report: @error', [
        '@error' => $e->getMessage(),
      ]);
      return [
        '#type' => 'container',
        '#attributes' => ['class' => ['error-message']],
        'message' => [
          '#markup' => '<p>' . $this->t('An error occurred while generating the report.') . '</p>',
        ],
      ];
    }
  }

  /**
   * Gets a formatted module status.
   *
   * @param int $errors
   *   Number of errors.
   * @param int $warnings
   *   Number of warnings.
   *
   * @return array
   *   A render array for the status.
   */
  protected function getModuleStatus($errors, $warnings) {
    if ($errors === 0 && $warnings === 0) {
      return [
        '#type' => 'html_tag',
        '#tag' => 'span',
        '#value' => $this->t('Compatible'),
        '#attributes' => ['class' => ['status-compatible']],
      ];
    }
    elseif ($errors === 0) {
      return [
        '#type' => 'html_tag',
        '#tag' => 'span',
        '#value' => $this->t('Needs Update'),
        '#attributes' => ['class' => ['status-needs-update']],
      ];
    }
    else {
      return [
        '#type' => 'html_tag',
        '#tag' => 'span',
        '#value' => $this->t('Incompatible'),
        '#attributes' => ['class' => ['status-incompatible']],
      ];
    }
  }
}

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

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