auto_alter-8.x-1.x-dev/auto_alter.module

auto_alter.module
<?php

/**
 * @file
 * Contains auto_alter.module.
 */

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Url;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\file\Entity\File;
use Masterminds\HTML5;

/**
 * Implements hook_modules_installed().
 */
function auto_alter_modules_installed($modules) {
  if (in_array('auto_alter', $modules)) {
    \Drupal::messenger()->addStatus(t('API key and Endpoint URL is not set and it is required for the module to work. Please set it up at the <a href=":settings">Image Automatic Alternative Text settings page</a>.', [
      ':settings' => Url::fromRoute('auto_alter.settings')->toString(),
    ]));
  }
}

/**
 * Implements hook_entity_presave().
 */
function auto_alter_entity_presave(EntityInterface $entity) {
  // Handle translation population if enabled.
  $config = \Drupal::config('auto_alter.settings');

  // Check if entity is translatable before calling translation methods.
  if ($config->get('alttext_ai_auto_populate_translations')
      && $entity instanceof ContentEntityInterface
      && $entity->isTranslatable()
      && !$entity->isDefaultTranslation()) {
    $target_language = $entity->language()->getId();
    $tempstore = \Drupal::service('tempstore.private')->get('auto_alter');
    $descriptions = $tempstore->get('last_descriptions');

    if ($descriptions && is_array($descriptions) && isset($descriptions[$target_language])) {
      $entity_manager = \Drupal::service('entity_field.manager');
      foreach ($entity_manager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle()) as $field_name => $field_definition) {
        if ($field_definition->getType() === 'image') {
          $field_items = $entity->get($field_name);
          foreach ($field_items as $delta => $item) {
            $current_alt = $item->alt ?? '';
            $source_alt = $entity->getUntranslated()->get($field_name)->get($delta)->alt ?? '';
            if (empty($current_alt) || $current_alt === $source_alt) {
              $item->alt = $descriptions[$target_language];
            }
          }
        }
      }
    }
    return;
  }

  $suggestion = \Drupal::config('auto_alter.settings')->get('suggestion');
  if (empty($suggestion)) {
    return;
  }
  if (empty($suggestion)) {
    return;
  }

  if ($entity instanceof ContentEntityInterface) {
    $entity_manager = \Drupal::service('entity_field.manager');
    foreach ($entity_manager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle()) as $field_name => $field_definition) {
      if (!empty($field_definition->getTargetBundle())) {
        if ($field_definition->getType() == 'image') {
          $images = $entity->get($field_name);
          foreach ($images as $key => $image) {
            if (empty($image->alt)) {
              $images[$key]->alt = auto_alter_get_description($image->target_id);
            }
          }
        }
      }
      if ($field_definition->getType() == 'text_with_summary') {
        $texts = $entity->get($field_name);
        $changed = false;
        foreach ($texts as $key => $text) {
          $raw = $text->getValue();
          $html5 = new HTML5(['disable_html_ns' => TRUE]);
          $dom = $html5->loadHTML($raw['value']);



          foreach($dom->getElementsByTagName('img') as $imgs) {
            $nodes = [];
            foreach($imgs as $img) {
              $nodes['alt'] = $imgs->getAttribute('alt');
              $nodes['src'] = $imgs->getAttribute('src');
              $nodes['data-entity-uuid'] = $imgs->getAttribute('data-entity-uuid');
            }
            if (empty($nodes['alt'])) {
              $changed = true;
              $file = \Drupal::service('entity.repository')->loadEntityByUuid('file', $nodes['data-entity-uuid']);
              if ($file instanceof File) {
                $fid = $file->id();
                $mime = $file->getMimeType();
                if (strpos($mime,'image/') !== false) {
                  $description = auto_alter_get_description($file->id());
                  $raw['value'] = str_replace('data-entity-uuid="' . $nodes['data-entity-uuid'] . '"',
                    'data-entity-uuid="' .   $nodes['data-entity-uuid'] . '" alt="' . $description . '"', $raw['value']);
                }
              }
            }
          }
          $text->value = $raw['value'];
          $texts[$key] = $text;
        }
        if ($changed) {
          $entity->{$field_name} = $texts;
        }
      }
    }
  }
}

/**
 * Implements hook_form_alter().
 */
function auto_alter_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $suggestion = \Drupal::config('auto_alter.settings')->get('suggestion');
  if ($suggestion) {
    if (isset($form['#entity_builders'])) {
      $entity = $form_state->getFormObject()->getEntity();
      $entity_manager = \Drupal::service('entity_field.manager');
      if (!($entity instanceof FieldableEntityInterface)) {
        return;
      }
      foreach ($entity_manager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle()) as $field_name => $field_definition) {
        if (!empty($field_definition->getTargetBundle())) {
          if ($field_definition->getType() == 'image') {
            $images = $entity->get($field_name);
            foreach ($images as $key => $image) {
              $entity_manager = \Drupal::entityTypeManager();
              if (isset($form[$field_name]['widget'][$key]) && $form[$field_name]['widget'][$key]['#alt_field'] && isset($form[$field_name]['widget'][$key]['#default_value']['alt']) && empty($form[$field_name]['widget'][$key]['#default_value']['alt'])) {
                $form[$field_name]['widget'][$key]['#default_value']['alt'] = auto_alter_get_description($form[$field_name]['widget'][$key]['#default_value']['fids'][0]);
              }
            }
          }
        }
      }
    }
    elseif ($form_id === 'media_directories_add_form' || $form_id === 'media_library_add_form_dropzonejs') {
      $entity_type = 'media';
      if (!empty($form_state->getStorage()[$entity_type])) {
        $entity = $form_state->getStorage()[$entity_type][0];
        $entity_manager = \Drupal::service('entity_field.manager');
        if (!($entity instanceof FieldableEntityInterface)) {
          return;
        }
        foreach ($entity_manager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle()) as $field_name => $field_definition) {
          if (!empty($field_definition->getTargetBundle())) {
            if ($field_definition->getType() === 'image') {
              $images = $entity->get($field_name);
              foreach ($images as $key => $image) {
                if (isset($form['media'][0]['fields'][$field_name]['widget'][$key]) && $form['media'][0]['fields'][$field_name]['widget'][$key]['#alt_field'] && empty($form['media'][0]['fields'][$field_name]['widget'][$key]['#default_value']['alt'])) {
                  $form['media'][0]['fields'][$field_name]['widget'][$key]['#default_value']['alt'] = auto_alter_get_description($form['media'][0]['fields'][$field_name]['widget'][$key]['#default_value']['fids'][0]);
                }
              }
            }
          }
        }
      }
    }
    elseif ($form_id === 'media_library_add_form_upload') {
      $triggering_element = $form_state->getTriggeringElement();
      if (!empty($triggering_element) && $triggering_element['#name'] === 'upload_upload_button' && $form_state->getValue('upload')) {
        $entity_type = 'media';
        if (!empty($form_state->getStorage()[$entity_type])) {
          $entity = $form_state->getStorage()[$entity_type][0];
          $entity_manager = \Drupal::service('entity_field.manager');
          if (!($entity instanceof FieldableEntityInterface)) {
            return;
          }
          foreach ($entity_manager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle()) as $field_name => $field_definition) {
            if (!empty($field_definition->getTargetBundle())) {
              if ($field_definition->getType() === 'image') {
                $images = $entity->get($field_name);
                foreach ($images as $key => $image) {
                  if (isset($form['media'][0]['fields'][$field_name]['widget'][$key]) && $form['media'][0]['fields'][$field_name]['widget'][$key]['#alt_field'] && empty($form['media'][0]['fields'][$field_name]['widget'][$key]['#default_value']['alt'])) {
                    $form['media'][0]['fields'][$field_name]['widget'][$key]['#default_value']['alt'] = auto_alter_get_description($form['media'][0]['fields'][$field_name]['widget'][$key]['#default_value']['fids'][0]);
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  if (isset ($form_id) && $form_id == 'editor_image_dialog' ) {
    //Set a wrapper for the ajax petition.
    $form['suggestion'] = array(
      '#type' => 'button',
      '#value' => t('Get suggestion'),
      '#limit_validation_errors' => [],
    );
    $fid = $form_state->getValue('fid');
    if ($fid != null && (isset($fid[0]) || isset($fid['fids'][0]))) {
     // $form['suggestion']['#attributes']['disabled']  = FALSE;
    }
    else {
     // $form['suggestion']['#attributes']['disabled']  = TRUE;
    }
    $form['suggestion']['#prefix'] = '<div id="edit-alternative">';
    $form['suggestion']['#suffix'] = '</div>';
    $form['suggestion']['#ajax'] = [
      'callback' => 'getAlternativeText',
      'event' => 'click',
      'wrapper' => 'editor-image-dialog-form',
    ];
    $form['suggestion']['#weight'] = -5;
    $form['attributes']['#weight'] = -10;
    $form['fid']['#weight'] = -15;
      /*
      $form['attributes']['alt']['#ajax'] = [
        'callback' => 'disableButton',
        'event' => 'change',
        'wrapper' => 'edit-alternative',
      ];
      */
    }
  }

  /**
   * @param array $form
   * @param FormStateInterface $form_state
   * @return AjaxResponse
   */
function getAlternativeText(array &$form, FormStateInterface $form_state) {
  $fid = $form_state->getValue('fid');
  if ($fid != null && isset($fid[0])) {
    if (empty($form['attributes']['alt']['#value'])) {
      $form['attributes']['alt']['#value'] = auto_alter_get_description($fid[0]);
    }
  }
  elseif ($fid != null && isset($fid['fids'][0])) {
    $form['attributes']['alt']['#value'] = auto_alter_get_description($fid['fids'][0]);
  }
  return $form;
}

function disableButton(array &$form, FormStateInterface $form_state) {
  if (!empty($form['attributes']['alt']['#value'])) {
    $form['suggestion']['#attributes']['disabled']  = TRUE;
  }
  else {
    $form['suggestion']['#attributes']['disabled']  = FALSE;
  }
  return $form['suggestion'];
}

/**
 * Implements auto_alter_get_description($fid).
 *
 * @param int $fid
 *   File ID.
 */
function auto_alter_get_description($fid) {
  $engine = auto_alter_get_engine();
  if ($engine->checkSetup() === FALSE) {
    \Drupal::messenger()->addStatus(
      t('The selected AI engine is not set and it is required for the module to work. Please set it up at the <a href=":settings">Image Automatic Alternative Text settings page</a>.', [
        ':settings' => Url::fromRoute('auto_alter.settings')->toString(),
      ])
    );
    return '';
  }
  $entity_manager = \Drupal::entityTypeManager();
  $file = $entity_manager->getStorage('file')->load($fid);
  $uri = $engine->getUri($file);
  $alternate_text = auto_alter_get_description_by_uri($uri);

  return $alternate_text;

}

function auto_alter_get_description_by_uri($uri) {
  $engine = auto_alter_get_engine();

  $status = \Drupal::config('auto_alter.settings')->get('status');
  $path = \Drupal::service('file_system')->realpath($uri);
  $path = $path ? $path : $uri;
  $description = $engine->getDescription($path);
  if (!empty($description)) {
    $alternate_text = $description;

    $moduleHandler = \Drupal::service('module_handler');
    if ($moduleHandler->moduleExists('auto_alter_translate')) {
      $active = \Drupal::config('auto_alter_translate.settings')->get('active');
      $engine = \Drupal::configFactory()->getEditable('auto_alter.settings')->get('engine');
      $region = \Drupal::config('auto_alter_translate.settings')
        ->get('region');
      if ($active && $engine == 'azure_cognitive_services') {
        $request = \Drupal::service('auto_alter_translate.get_translation')->gettranslation($alternate_text, $region);
        if (!empty($request) && $request->getStatusCode() == 200) {
          $trans = (array) json_decode($request->getBody());
          $alternate_text = $trans[0]->translations[0]->text;
        }
      }
    }
    if ($status) {
      \Drupal::messenger()->addStatus(t('Alternate text has been changed to: %text"', ['%text' => $alternate_text]));
    }
    return $alternate_text;
  }
  else {
    if ($status) {
      \Drupal::messenger()->addWarning(t('Automatic generation of Alternate text has failed'));
    }
    return '';
  }

}
/**
 * Returns the currently selected engine.
 *
 * @return \Drupal\auto_alter\DescribeImageServiceInterface
 *   The currently selected engine.
 *
 * @throws \Drupal\Component\Plugin\Exception\PluginException
 */
function auto_alter_get_engine() {
  $engine = \Drupal::config('auto_alter.settings')->get('engine');
  /** @var \Drupal\auto_alter\Plugin\AutoAlterDescribeImagePluginManager $plugin_manager */
  $plugin_manager = \Drupal::service('plugin.manager.auto_alter_describe_image');
  /** @var \Drupal\auto_alter\DescribeImageServiceInterface $plugin */
  $plugin = $plugin_manager->createInstance($engine);
  return $plugin;
}

/**
 * Implements hook_entity_translation_create().
 */
function auto_alter_entity_translation_create(\Drupal\Core\Entity\EntityInterface $translation) {
  // Check if auto-populate translations is enabled.
  $config = \Drupal::config('auto_alter.settings');
  if (!$config->get('alttext_ai_auto_populate_translations')) {
    return;
  }

  // Only process content entities that are translatable.
  if (!($translation instanceof \Drupal\Core\Entity\ContentEntityInterface) || !$translation->isTranslatable()) {
    return;
  }

  // Only process if this is a new translation (not the source).
  if ($translation->isDefaultTranslation()) {
    return;
  }

  $target_language = $translation->language()->getId();

  // Get all image fields on this entity.
  $image_fields = [];
  foreach ($translation->getFieldDefinitions() as $field_name => $field_definition) {
    if ($field_definition->getType() === 'image') {
      $image_fields[] = $field_name;
    }
  }

  if (empty($image_fields)) {
    return;
  }

  // Process each image field.
  foreach ($image_fields as $field_name) {
    if (!$translation->hasField($field_name)) {
      continue;
    }

    $field_items = $translation->get($field_name);

    foreach ($field_items as $delta => $item) {
      // Get the source alt text.
      $source_alt = $translation->getUntranslated()->get($field_name)->get($delta)->alt ?? '';

      if (empty($source_alt)) {
        continue;
      }

      // Get the file entity.
      $file = $item->entity;
      if (!$file) {
        continue;
      }

      // Try to get translated alt text.
      $translated_alt = auto_alter_get_translated_alt($file, $target_language);

      if ($translated_alt) {
        $item->alt = $translated_alt;
      }
    }
  }
}

/**
 * Get translated alt text for a file.
 *
 * @param \Drupal\file\Entity\File $file
 *   The file entity.
 * @param string $target_language
 *   The target language code.
 *
 * @return string|null
 *   The translated alt text, or NULL if not available.
 */
function auto_alter_get_translated_alt($file, $target_language) {
  try {
    $engine = auto_alter_get_engine();

    // Check if engine supports multi-language.
    if (!method_exists($engine, 'getDescriptions')) {
      return NULL;
    }

    $uri = $engine->getUri($file);
    $path = \Drupal::service('file_system')->realpath($uri);
    $path = $path ? $path : $uri;

    // Get all descriptions.
    $descriptions = $engine->getDescriptions($path);

    // Return the translation for target language if available.
    return $descriptions[$target_language] ?? NULL;
  }
  catch (\Exception $e) {
    \Drupal::logger('auto_alter')->error('Error getting translated alt text: @error', [
      '@error' => $e->getMessage(),
    ]);
    return NULL;
  }
}

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

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