vais_promos-1.0.0-beta2/src/Form/VaisImportXmlForm.php

src/Form/VaisImportXmlForm.php
<?php

namespace Drupal\vais_promos\Form;

use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\search\SearchPageRepositoryInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Form to import promotions from an XML file.
 */
class VaisImportXmlForm extends FormBase {

  /**
   * The messenger object.
   *
   * @var \Drupal\Core\Messenger\MessengerInterface
   */
  protected $messenger;

  /**
   * The search page repository object.
   *
   * @var \Drupal\search\SearchPageRepositoryInterface
   */
  protected $searchPageRepo;

  /**
   * The database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $database;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountProxy
   */
  protected $currentUser;

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

  /**
   * The constructor for the XML import form.
   *
   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
   *   The messenger object.
   * @param \Drupal\search\SearchPageRepositoryInterface $searchPageRepo
   *   The search page repository object.
   * @param \Drupal\Core\Database\Connection $database
   *   The database connection.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The entity type manager.
   * @param \Drupal\Core\Session\AccountProxyInterface $currentUser
   *   The current user.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
   *   The module handler.
   */
  public function __construct(MessengerInterface $messenger, SearchPageRepositoryInterface $searchPageRepo, Connection $database, EntityTypeManagerInterface $entityTypeManager, AccountProxyInterface $currentUser, ModuleHandlerInterface $moduleHandler) {
    $this->messenger = $messenger;
    $this->searchPageRepo = $searchPageRepo;
    $this->database = $database;
    $this->entityTypeManager = $entityTypeManager;
    $this->currentUser = $currentUser;
    $this->moduleHandler = $moduleHandler;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('messenger'),
      $container->get('search.search_page_repository'),
      $container->get('database'),
      $container->get('entity_type.manager'),
      $container->get('current_user'),
      $container->get('module_handler'),
    );
  }

  /**
   * Returns a unique string identifying the form.
   *
   * @return string
   *   The unique string identifying the form.
   */
  public function getFormId(): string {
    return 'vais_promo_import_xml';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['description'] = [
      '#markup' => 'The importer will try and match the promotion URL with existing content, and only creates internal linked promotions.',
    ];

    // Get list of available Vertex AI search pages.
    $searchPageOptions = [];
    $activeSearchPages = $this->searchPageRepo->getActiveSearchPages();
    foreach ($this->searchPageRepo->sortSearchPages($activeSearchPages) as $entity) {
      if ($entity->get('plugin') === 'vertex_ai_search') {
        $searchPageOptions[$entity->id()] = $entity->label();
      }
    }

    $form['promo_search_page'] = [
      '#type' => 'select',
      '#title' => $this->t('Vertex AI Search Page'),
      '#description' => $this->t('The Vertex AI Search Page on which this Promotion will appear.'),
      '#options' => $searchPageOptions,
      '#required' => TRUE,
    ];

    if (count($searchPageOptions) === 1) {
      $form['promo_search_page']['#default_value'] = implode(",", array_keys($searchPageOptions));
    }

    $form['import_xml'] = [
      '#type' => 'file',
      '#required' => TRUE,
      '#title' => $this->t('XML file'),
      '#description' => $this->t('Upload a .xml file that was exported from <a href="@link">Google Programmable Search</a>.',
        [
          '@link' => 'https://developers.google.com/custom-search/docs/promotions',
        ]
      ),
    ];

    $form['actions'] = [
      '#type' => 'actions',
    ];

    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#name' => 'vais_promo_import_xml',
      '#value' => $this->t('Import'),
      '#button_type' => 'primary',
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $files = file_save_upload('import_xml', ['file_validate_extensions' => ['xml']]);
    $xml_file = $files[0];
    if (!$files || empty($xml_file)) {
      $this->messenger->addError("There was an error uploading the file.");
    }
    else {
      $xml_data = file_get_contents($xml_file->getFileUri());
      $xml_object = simplexml_load_string($xml_data);

      $total_added = $total_external = 0;
      foreach ($xml_object->Promotion as $promo) {

        // Get an entity_id from the URL.
        $nid = NULL;
        $url = $promo->attributes()->url[0];
        $url_parts = parse_url($url);
        $alias = $url_parts['path'];
        $pathParts = explode('/', trim($alias, " /"));
        $promoType = 'internal';

        if ($pathParts[0] == 'node' && is_numeric($pathParts[1])) {
          // Check if nid is explicitly in a 'node/nid' path.
          $nid = $pathParts[1];
        }

        if ((!$nid || !is_numeric($nid)) &&
          $this->moduleHandler->moduleExists('redirect')) {
          // Check for a redirect, and trim the leading slash from the alias.
          $query = $this->database->select('redirect', 'r');
          $query->addExpression("REPLACE(r.redirect_redirect__uri, 'internal:/node/', '')", 'nid');
          $query->condition('r.redirect_source__path', trim($alias, " /"), '=');
          $nid = $query->execute()->fetchField();
        }

        if (!$nid || !is_numeric($nid)) {
          // Now look for the node ID by alias.
          $query = $this->database->select('path_alias', 'p');
          $query->addExpression("REPLACE(p.path, '/node/', ''), 'path'");
          $query->condition('p.alias', $alias, '=');
          $nid = $query->execute()->fetchField();
        }

        // If none exists, treat promo link as external.
        if (!$nid || !is_numeric($nid)) {
          $total_external++;
          $promoType = 'external';
        }

        $options = [
          'promo_search_page' => $form_state->getValue('promo_search_page'),
          'promo_trigger' => implode(",", (array) $promo->Query),
          'promo_type' => $promoType,
          'promo_content' => $nid ?? NULL,
          'promo_link' => empty($nid) ? $url : NULL,
          'promo_title_override' => (string) $promo->attributes()->title[0],
          'promo_description' => ((string) $promo->attributes()->description) ?: NULL,
          'user_id' => $this->currentUser->id(),
        ];

        try {
          $new_promo = $this->entityTypeManager->getStorage('vais_promo')->create($options);
          $new_promo->save();
        }
        catch (\Exception $e) {
          $this->messenger->addError($e->getMessage());
        }

        $total_added++;
      }

      if ($total_external > 0) {
        $this->messenger->addMessage("Imported $total_added promotions, $total_external link to external resources.");
      }
      else {
        $this->messenger->addMessage("Imported $total_added promotions");
      }
    }
  }

}

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

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