ai_upgrade_assistant-0.2.0-alpha2/src/Form/SettingsForm.php
src/Form/SettingsForm.php
<?php
namespace Drupal\ai_upgrade_assistant\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\State\StateInterface;
use Drupal\ai_upgrade_assistant\Service\EnvironmentDetector;
use Drupal\Core\Url;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Cache\CacheBackendInterface;
/**
* Configuration form for AI Upgrade Assistant settings.
*/
class SettingsForm extends ConfigFormBase {
/**
* The module handler service.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The file system service.
*
* @var \Drupal\Core\File\FileSystemInterface
*/
protected $fileSystem;
/**
* The environment detector service.
*
* @var \Drupal\ai_upgrade_assistant\Service\EnvironmentDetector
*/
protected $environmentDetector;
/**
* The state service.
*
* @var \Drupal\Core\State\StateInterface
*/
protected $state;
/**
* The logger factory service.
*
* @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
*/
protected $loggerFactory;
/**
* The cache backend.
*
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected $cache;
/**
* Constructs a SettingsForm object.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory service.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler service.
* @param \Drupal\Core\File\FileSystemInterface $file_system
* The file system service.
* @param \Drupal\Core\State\StateInterface $state
* The state service.
* @param \Drupal\ai_upgrade_assistant\Service\EnvironmentDetector $environment_detector
* The environment detector service.
* @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
* The logger factory service.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache
* The cache backend.
*/
public function __construct(
ConfigFactoryInterface $config_factory,
ModuleHandlerInterface $module_handler,
FileSystemInterface $file_system,
StateInterface $state,
EnvironmentDetector $environment_detector,
LoggerChannelFactoryInterface $logger_factory,
CacheBackendInterface $cache
) {
parent::__construct($config_factory);
$this->moduleHandler = $module_handler;
$this->fileSystem = $file_system;
$this->state = $state;
$this->environmentDetector = $environment_detector;
$this->loggerFactory = $logger_factory;
$this->cache = $cache;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('config.factory'),
$container->get('module_handler'),
$container->get('file_system'),
$container->get('state'),
$container->get('ai_upgrade_assistant.environment_detector'),
$container->get('logger.factory'),
$container->get('cache.default')
);
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return ['ai_upgrade_assistant.settings'];
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'ai_upgrade_assistant_settings';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
$form['#attached']['library'][] = 'ai_upgrade_assistant/config_page_library';
$form['#theme'] = 'ai_upgrade_assistant_config';
// Check if we're in a local development environment
if (!$this->environmentDetector->isLocalDevelopment()) {
$form['error'] = [
'#type' => 'markup',
'#markup' => $this->t('<div class="messages messages--error">ERROR: This appears to be a production environment. This module must only be used in local development environments.</div>'),
];
return $form;
}
// API Settings
$form['api_settings'] = [
'#type' => 'container',
'huggingface_token' => [
'#type' => 'password',
'#title' => $this->t('HuggingFace API Token'),
'#description' => $this->t('Get your token from HuggingFace Settings. This is required to access the AI models.'),
'#required' => TRUE,
'#default_value' => $this->state->get('ai_upgrade_assistant.huggingface_token'),
'#attributes' => ['autocomplete' => 'off'],
],
'model_id' => [
'#type' => 'textfield',
'#title' => $this->t('Model ID'),
'#description' => $this->t('The HuggingFace model ID to use (e.g., "drupal/ai-upgrade-patterns")'),
'#default_value' => $this->config('ai_upgrade_assistant.settings')->get('model_id') ?: 'drupal/ai-upgrade-patterns',
'#required' => TRUE,
],
];
// Analysis Settings
$form['analysis_settings'] = [
'#type' => 'container',
'batch_size' => [
'#type' => 'number',
'#title' => $this->t('Batch Size'),
'#description' => $this->t('Number of files to analyze in each batch.'),
'#default_value' => $this->config('ai_upgrade_assistant.settings')->get('batch_size') ?: 50,
'#min' => 1,
'#max' => 100,
],
'file_patterns' => [
'#type' => 'textfield',
'#title' => $this->t('File Patterns'),
'#description' => $this->t('Comma-separated list of file patterns to analyze (e.g., *.php,*.module,*.inc)'),
'#default_value' => $this->config('ai_upgrade_assistant.settings')->get('file_patterns') ?: '*.php,*.module,*.inc,*.install',
],
'excluded_paths' => [
'#type' => 'textfield',
'#title' => $this->t('Excluded Paths'),
'#description' => $this->t('Comma-separated list of paths to exclude (e.g., vendor/,node_modules/)'),
'#default_value' => $this->config('ai_upgrade_assistant.settings')->get('excluded_paths') ?: 'vendor/,node_modules/,tests/',
],
];
// Privacy Settings
$form['privacy_settings'] = [
'#type' => 'container',
'maintenance_mode' => [
'#type' => 'checkbox',
'#title' => $this->t('Enable Maintenance Mode'),
'#description' => $this->t('Enable maintenance mode while making upgrades.'),
'#default_value' => $this->state->get('system.maintenance_mode', FALSE),
],
'debug_mode' => [
'#type' => 'checkbox',
'#title' => $this->t('Debug Mode'),
'#description' => $this->t('Enable detailed logging for debugging.'),
'#default_value' => $this->config('ai_upgrade_assistant.settings')->get('debug_mode') ?: FALSE,
],
];
// Advanced Settings
$form['advanced_settings'] = [
'#type' => 'container',
'parallel_processing' => [
'#type' => 'checkbox',
'#title' => $this->t('Enable Parallel Processing'),
'#description' => $this->t('Use multiple processes to speed up analysis. May increase memory usage.'),
'#default_value' => $this->config('ai_upgrade_assistant.settings')->get('parallel_processing') ?: FALSE,
],
'cache_ttl' => [
'#type' => 'number',
'#title' => $this->t('Cache TTL'),
'#description' => $this->t('Time in seconds to cache analysis results.'),
'#default_value' => $this->config('ai_upgrade_assistant.settings')->get('cache_ttl') ?: 3600,
'#min' => 0,
],
];
// Report Settings
$form['report_settings'] = [
'#type' => 'container',
'report_formats' => [
'#type' => 'checkboxes',
'#title' => $this->t('Report Formats'),
'#description' => $this->t('Select the formats for generated reports.'),
'#options' => [
'html' => $this->t('HTML'),
'json' => $this->t('JSON'),
'markdown' => $this->t('Markdown'),
],
'#default_value' => $this->config('ai_upgrade_assistant.settings')->get('report_formats') ?: ['html', 'json'],
],
'report_directory' => [
'#type' => 'textfield',
'#title' => $this->t('Report Directory'),
'#description' => $this->t('Directory where reports will be saved.'),
'#default_value' => $this->config('ai_upgrade_assistant.settings')->get('report_directory') ?: 'public://ai-upgrade-reports',
],
];
// Actions
$form['actions']['#attributes']['class'][] = 'ai-form-actions';
$form['actions']['submit']['#attributes']['class'][] = 'ai-button';
$form['actions']['submit']['#attributes']['class'][] = 'ai-button--primary';
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
// Validate report directory
$report_dir = $form_state->getValue('report_directory');
if (!$this->fileSystem->prepareDirectory($report_dir, FileSystemInterface::CREATE_DIRECTORY)) {
$form_state->setError($form['report']['report_directory'], $this->t('Unable to create or access report directory.'));
}
// Validate batch size
$batch_size = $form_state->getValue('batch_size');
if ($batch_size < 1 || $batch_size > 100) {
$form_state->setError($form['analysis']['batch_size'], $this->t('Batch size must be between 1 and 100.'));
}
// Validate HuggingFace token if provided
$huggingface_token = $form_state->getValue(['huggingface', 'huggingface_token']);
if (!empty($huggingface_token) && !$this->validateHuggingFaceToken($huggingface_token)) {
$form_state->setError($form['huggingface']['huggingface_token'], $this->t('Invalid HuggingFace API token format.'));
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
parent::submitForm($form, $form_state);
$config = $this->configFactory->getEditable('ai_upgrade_assistant.settings');
// Save HuggingFace settings
$huggingface_token = trim($form_state->getValue(['huggingface', 'huggingface_token']));
if (!empty($huggingface_token)) {
// Debug log before saving
$this->loggerFactory->get('ai_upgrade_assistant')->debug('Saving HuggingFace token: @token', ['@token' => $huggingface_token]);
$this->state->set('ai_upgrade_assistant.huggingface_token', $huggingface_token);
$this->loggerFactory->get('ai_upgrade_assistant')->notice('HuggingFace API token has been updated.');
// Debug log after saving
$saved_token = $this->state->get('ai_upgrade_assistant.huggingface_token');
$this->loggerFactory->get('ai_upgrade_assistant')->debug('Saved HuggingFace token: @token', ['@token' => $saved_token]);
}
// Save model settings
$config->set('model_id', $form_state->getValue(['huggingface', 'model_id']));
// Save analysis settings
$config->set('batch_size', $form_state->getValue('batch_size'));
$config->set('file_patterns', $form_state->getValue('file_patterns'));
$config->set('excluded_paths', $form_state->getValue('excluded_paths'));
// Save report settings
$config->set('report_formats', $form_state->getValue('report_formats'));
$config->set('report_directory', $form_state->getValue('report_directory'));
// Save advanced settings
$config->set('maintenance_mode', $form_state->getValue('maintenance_mode'));
$config->set('parallel_processing', $form_state->getValue('parallel_processing'));
$config->set('cache_ttl', $form_state->getValue('cache_ttl'));
$config->set('debug_mode', $form_state->getValue('debug_mode'));
$config->save();
// Clear relevant caches
$this->cache->deleteAll();
// Log success
$this->loggerFactory->get('ai_upgrade_assistant')->info('AI Upgrade Assistant settings have been updated.');
}
/**
* Gets a preview of patterns that will be shared publicly.
*
* @return array
* Array of pattern preview data.
*/
protected function getPatternPreview() {
// Implementation will be added in a separate PR
return [];
}
/**
* Gets statistics from the public dataset.
*
* @return array
* Array of dataset statistics.
*/
protected function getDatasetStatistics() {
// Implementation will be added in a separate PR
return [];
}
/**
* Validates a HuggingFace API token format.
*
* @param string $token
* The token to validate.
*
* @return bool
* TRUE if the token format is valid, FALSE otherwise.
*/
protected function validateHuggingFaceToken($token) {
// HuggingFace API tokens start with hf_
return !empty($token) && preg_match('/^hf_[a-zA-Z0-9-_]{32,}$/', $token);
}
}
