gotem_content_moderation-1.1.6-alpha1/src/Form/GotemSettingsForm.php
src/Form/GotemSettingsForm.php
<?php
namespace Drupal\gotem\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Configuration form for the Gotem module.
*/
class GotemSettingsForm extends ConfigFormBase {
/**
* The entity field manager service.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
/**
* Constructs a new GotemSettingsForm.
*
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
* The entity field manager service.
*/
public function __construct(EntityFieldManagerInterface $entity_field_manager) {
$this->entityFieldManager = $entity_field_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_field.manager')
);
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return ['gotem.settings'];
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'gotem_settings_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('gotem.settings');
$api_key = \Drupal::state()->get('gotem_content_moderation.api_key');
// Add a checkbox for turning moderation on/off.
$form['moderation_enabled'] = [
'#type' => 'checkbox',
'#title' => $this->t('Enable Moderation'),
'#description' => $this->t('Check this box to enable content moderation using OpenAI.'),
'#default_value' => $config->get('moderation_enabled') ?? TRUE, // Default to enabled.
];
// Group for API settings
$form['api_settings'] = [
'#type' => 'fieldset',
'#title' => $this->t('OpenAI API Settings'),
'#description' => $this->t('Enter your OpenAI API key for content moderation. This key is essential for moderation to work.'),
];
// API key field
$form['api_settings']['api_key'] = [
'#type' => 'textfield',
'#title' => $this->t('OpenAI API Key'),
'#placeholder' => $this->getPartialApiKey($api_key),
'#required' => TRUE,
'#description' => $this->t('Enter your OpenAI API key here. This key is required for content moderation using OpenAI\'s API.'),
'#maxlength' => 256,
'#size' => 64,
'#disabled' => !empty($api_key),
];
// Reset API key button
if (!empty($api_key)) {
$form['api_settings']['reset_api_key'] = [
'#type' => 'submit',
'#value' => $this->t('Reset API Key'),
'#submit' => ['::resetApiKey'],
'#button_type' => 'danger',
'#description' => $this->t('Click to reset your current API key.'),
];
}
// Bundle selection group
$form['bundle_selection'] = [
'#type' => 'fieldset',
'#title' => $this->t('Content Bundles to Moderate'),
'#description' => $this->t('Select the content bundles where moderation should be applied.'),
];
// Bundle selection checkboxes
$form['bundle_selection']['bundles'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Bundles'),
'#options' => $this->getBundleOptions(),
'#default_value' => $config->get('bundle_selection') ?: [],
'#required' => TRUE,
];
// Moderation thresholds using sliders
$form['threshold_settings'] = [
'#type' => 'fieldset',
'#title' => $this->t('Moderation Thresholds'),
'#description' => $this->t('Set thresholds for moderation categories. The higher the threshold, the stricter the moderation, meaning content must score higher to be flagged.'),
];
$thresholds = [
'hate' => $this->t('Hate Speech'),
'violence' => $this->t('Violence'),
'self-harm' => $this->t('Self-Harm'),
'sexual' => $this->t('Sexual Content'),
];
foreach ($thresholds as $key => $label) {
// Retrieve the config value and cast it to float.
$default_value = isset($config->get('thresholds')[$key]) ? (float) $config->get("thresholds.$key") : 0.5;
$form['threshold_settings'][$key] = [
'#type' => 'number',
'#title' => $label,
'#default_value' => $default_value,
'#min' => 0,
'#max' => 1,
'#step' => 0.01,
'#description' => $this->t('Set the threshold for %label moderation. A value between 0 (lenient) and 1 (strict).', ['%label' => $label]),
'#attributes' => [
'type' => 'range',
'min' => 0,
'max' => 1,
'step' => 0.01,
],
'#attached' => [
'library' => [
'gotem_content_moderation/range-slider',
],
],
];
}
// Moderated fields selection group
$form['moderated_fields'] = [
'#type' => 'fieldset',
'#title' => $this->t('Fields to Moderate'),
'#description' => $this->t('Select which fields to apply OpenAI moderation to.'),
];
$form['moderated_fields']['fields'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Moderated Fields'),
'#options' => $this->getModeratableFields(),
'#default_value' => $config->get('moderated_fields') ?: [],
'#required' => TRUE,
];
return parent::buildForm($form, $form_state);
}
/**
* Retrieves the available bundles for node and taxonomy entities.
*
* @return array
* An associative array of bundle machine names and labels.
*/
protected function getBundleOptions() {
$bundle_info = \Drupal::service('entity_type.bundle.info')->getAllBundleInfo();
$options = [];
// Collect bundles for both node and taxonomy_term.
foreach (['node', 'taxonomy_term'] as $entity_type) {
if (isset($bundle_info[$entity_type])) {
foreach ($bundle_info[$entity_type] as $bundle_name => $bundle) {
$options["$entity_type:$bundle_name"] = $this->t('@type: @label', [
'@type' => ucfirst($entity_type),
'@label' => $bundle['label'],
]);
}
}
}
return $options;
}
/**
* Retrieves fields eligible for moderation for both nodes and taxonomy terms.
*
* @return array
* Field machine names and their labels.
*/
protected function getModeratableFields() {
$fields = [];
$entity_types = ['node', 'taxonomy_term'];
$bundle_info = \Drupal::service('entity_type.bundle.info')->getAllBundleInfo();
foreach ($entity_types as $entity_type) {
if (isset($bundle_info[$entity_type])) {
foreach ($bundle_info[$entity_type] as $bundle_name => $bundle) {
$field_definitions = $this->entityFieldManager->getFieldDefinitions($entity_type, $bundle_name);
foreach ($field_definitions as $field_name => $field_definition) {
$field_type = $field_definition->getType();
if (in_array($field_type, ['text', 'text_long', 'string', 'string_long'])) {
// Differentiate between node and taxonomy in the label
if ($entity_type === 'node') {
$label = $field_definition->getLabel() . ' (Content)';
}
elseif ($entity_type === 'taxonomy_term') {
$label = $field_definition->getLabel() . ' (Taxonomy)';
}
$fields["$entity_type:$field_name"] = $label;
}
}
}
}
}
return $fields;
}
/**
* Reset the API key.
*/
public function resetApiKey(array &$form, FormStateInterface $form_state) {
\Drupal::state()->delete('gotem_content_moderation.api_key');
\Drupal::messenger()->addMessage($this->t('The API key has been reset.'));
$form_state->setRebuild(TRUE);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$api_key = $form_state->getValue('api_key');
$selected_bundles = array_filter($form_state->getValue('bundles'));
$selected_fields = array_filter($form_state->getValue('fields'));
$grouped_thresholds = [
'hate' => $form_state->getValue('hate'),
'violence' => $form_state->getValue('violence'),
'self-harm' => $form_state->getValue('self-harm'),
'sexual' => $form_state->getValue('sexual'),
];
\Drupal::state()->set('gotem_content_moderation.api_key', $api_key);
$this->config('gotem.settings')
->set('thresholds', $grouped_thresholds)
->set('bundle_selection', array_keys($selected_bundles))
->set('moderated_fields', array_keys($selected_fields))
->set('moderation_enabled', $form_state->getValue('moderation_enabled'))
->save();
parent::submitForm($form, $form_state);
}
/**
* Display a partial (masked) API key.
*
* @param string $api_key
* The full API key.
*
* @return string
* The masked API key.
*/
protected function getPartialApiKey($api_key) {
return $api_key ? substr($api_key, 0, 15) . str_repeat('*', strlen($api_key) - 4) : '';
}
}
