metrc-1.0.x-dev/modules/metrc_migrate/src/Plugin/migrate/source/MetrcPackageHarvUrl.php

modules/metrc_migrate/src/Plugin/migrate/source/MetrcPackageHarvUrl.php
<?php

namespace Drupal\metrc_migrate\Plugin\migrate\source;

use DateTime;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate_plus\Plugin\migrate\source\SourcePluginExtension;
use Drupal\migrate\Row;
use Drupal\mysql\Driver\Database\mysql\Schema;
use Drupal\Core\Entity\Query\QueryBase;
use Drupal\Core\Entity\Query;
use \Drupal\node\Entity\Node;
use ArrayIterator;
use ArrayObject;

/**
 * Source plugin for retrieving data via URLs.
 *
 * @MigrateSource(
 *   id = "metrc_url2"
 * )  
 */
class MetrcPackageHarvUrl extends SourcePluginExtension
{

  /**
   * The database connection for the map/message tables on the destination.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $database;

  /**
   * The source URLs to retrieve.
   *
   * @var array
   */
  protected $sourceUrls = [];

  /**
   * @var array
   */
  protected $configuration = [];

  /**
   * @var MigrationInterface
   */
  protected $migration;

  /**
   * The data parser plugin.
   *
   * @var \Drupal\migrate_plus\DataParserPluginInterface
   */
  protected $dataParserPlugin;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration)
  {
    $this->migration = $migration;
    // Get configs
    $siteConfig = \Drupal::config('metrc.application_settings');
    $configuration['license'] = $siteConfig->get('license_numbers');
    $configuration['base_url'] = $siteConfig->get('base_url');
    $configuration['urls'] = [$configuration['base_url'] .
      $configuration['path']];
    $this->configuration = $configuration;
    $urls = [];
    if (array_key_exists('by_type', $configuration)) {
      switch ($configuration['by_type']) {
        case 'lab_test':
          $urls = $this->labTest();
          break;
        case 'date':
          $start = $this->getStartDate();
          $urls = $this->addByDate($start);
          break;
        case 'default':
          $urls = $configuration['urls'];
        case 'custom':
          $this->setExistingUnPublished();
          $start = new DateTime();
          $start->setDate(2021, 1, 1);
          $urls = $this->addByDate($start);
          break;
        case 'wholesale':
          $start = new DateTime();
          $start->setDate(2021, 1, 1);
          $urls = $this->wholesale($start);
          break;
      }
    }

    if (array_key_exists('statuses', $configuration) && $configuration['statuses']) {
      $urls = $this->addStatuses($urls);
    };

    parent::__construct($configuration, $plugin_id, $plugin_definition, $migration);
    $this->migration->setTrackLastImported(True);
    $urls = $this->addLicense($urls);
    $this->sourceUrls = $urls;
    $this->configuration['urls'] = $urls;

    if (!isset($this->database)) {
      $this->database = \Drupal::database();
    }
  }

  public function wholesale($start) {
    $schema1 = new Schema(\Drupal::database());
    // first get a list of all the delivery Ids in last (timeperiod var). And add that to this->ids.
    if ($schema1->tableExists('node')) {
        $deliveries = \Drupal::database()->select('node', 'd')
        ->fields('d', ['nid'])
        ->condition('d.type',  "delivery", '=')
        ->execute()
        ->fetchAll();
    };

    foreach ($deliveries as $delivery) {
      if (isset($delivery)) {
        $urls[] = $this->configuration['base_url'] . $this->configuration['path'] . '/' .$delivery->nid . "/packages/wholesale";
      };
    }
    return $urls;
  }

  /**
   * {@inheritdoc}
   */
  public function prepareRow(Row $row)
  {
    return parent::prepareRow($row);
  }


  /**
   * Add license number to the urls
   * 
   * @param array $urls
   * 
   * @return array
   */
  protected function addLicense(array $urls): array
  {
    foreach ($urls as $key => $url) {
      $delemeter = '&';
      if (!str_contains($url, '?')) {
        $delemeter = '?';
      }
      $urls[$key] .= $delemeter . 'licenseNumber=' .
        $this->configuration['license'];
    }

    return $urls;
  }

  protected function addStatuses(array $urls): array
  {
    $statusUrls = [];
    foreach ($urls as $url) {
      $urlParts = explode("?", $url);
      foreach ($this->configuration['statuses'] as $status) {
        $urlArray = $urlParts;
        $urlArray[0] .= "/$status";
        $statusUrls[] = implode("?", $urlArray);
      }
    }

    return $statusUrls;
  }

  /**
   * Get the date to start querying 
   * 
   * @param int|null $startTime
   * @param array $configuration
   * 
   * @return DateTime
   */
  protected function getStartDate(): DateTime
  {
    // Get last run time
    $start_unix = \Drupal::keyValue('migrate_last_imported')
      ->get($this->migration->id(), NULL);
    $start_unix = microtime(TRUE);
    $twoDaysAgo = new DateTime('now');
    $twoDaysAgo->modify('-2 days');
    $startTime = date("Y-m-d", $start_unix);
    $twoDaysAgo->format("Y-m-d");
    // use last runtime if greater than 2 days ago
    if ($startTime == null || ($startTime < $twoDaysAgo)) {
      $start = $twoDaysAgo;
    } else {
      $start = $startTime;
    };

    return $start;
  }

  /**
   * Build an array of URLs to query
   * 
   * @return array of urls
   */
  protected function addByDate(DateTime $start): array
  {
    $urls = [];
    // set end time (the end of current day)
    $end = new DateTime();
    $end->format("Y-m-d");
    // Daylight savings fix for metrc systems 24hr limit requirement
    $daylightsav = [];
    $daylightsav[0] = date_create("2020-11-01");
    $daylightsav[0]->format("Y-m-d");
    $daylightsav[1] = date_create("2021-11-07");
    $daylightsav[1]->format("Y-m-d");
    $daylightsav[2] = date_create("2022-11-06");
    $daylightsav[2]->format("Y-m-d");
    $daylightsav[3] = date_create("2023-11-05");
    $daylightsav[3]->format("Y-m-d");
    $daylightsav[4] = date_create("2024-11-03");
    $daylightsav[4]->format("Y-m-d");
    $daylightsav[5] = date_create("2024-11-02");
    $daylightsav[5]->format("Y-m-d");

    // Create the url dates
    for ($start->format("Y-m-d"); $start < $end; $start->modify('+1 day')) {
      $start_copy = clone $start;
      $stop = $start_copy->modify('+1 day');
      // check daylight savings
      $current_timeless = clone $start;
      $current_timeless = $start->setTime(
        $hour = 0,
        $minute = 0,
        $second = 0,
        $microsecond = 0
      );
      for ($yr = 0; $yr < 6; $yr++) {
        if ($current_timeless == $daylightsav[$yr]) {
          $stop->modify('-2 hours');
        };
      };
      // set URLs
      $urls[] = $this->configuration['base_url'] . $this->configuration['path'] .
        '?lastModifiedStart=' . $start->format("Y-m-d") .
        '&lastModifiedEnd=' . $stop->format("Y-m-d");
    };
    return $urls;
  }

  /**
   *   Note it only works on Active packages. Returns lab test urls.
   * 
   * @return array
   */
  protected function labTest(): array
  {
    $packages = [];
  
    $schema1 = new Schema(\Drupal::database());
    // first get a list of all the harvest tid numbers. And add that to this->ids.
    if ($schema1->tableExists('taxonomy_term_revision__field_harvest_state') && ($schema1->tableExists('migrate_map_lab_test'))) {
      $packages = [];
      $harvests = \Drupal::database()->select('taxonomy_term_revision__field_harvest_state', 'hs')
        ->fields('hs', ['entity_id'])
        ->condition('hs.field_harvest_state_value', '1', '=')
        ->execute()
        ->fetchAll();
      if (!empty($harvests)) {
        foreach ($harvests as $delta => $harvest) {
          $harv_pkg =  \Drupal::entityTypeManager()->getStorage('node')->getQuery()
            ->accessCheck(FALSE)
            ->condition('type', 'package')
            ->condition('field_sourceharvestnames', $harvest->entity_id, '=')
            ->condition('field_package_state', 'active', '=')
            ->condition('status', Node::PUBLISHED)
            ->latestRevision()
            ->range(0, 1)
            ->execute();

          if (isset($harv_pkg)) {
            $pkg_array = new ArrayObject($harv_pkg);
            $pkg_itterator = $pkg_array->GetIterator();
            $packages[] = $pkg_itterator->current();
          };
        };
      }
    };

    foreach ($packages as $packageId) {
      if (isset($packageId)) {
        $urls[] = $this->configuration['base_url'] . $this->configuration['path'] .
          "?packageId=$packageId";
      };
    }
    return $urls;
  }

  /**
   * Return a string representing the source URLs.
   *
   * @return string
   *   Comma-separated list of URLs being imported.
   */
  public function __toString()
  {
    // This could cause a problem when using a lot of urls, may need to hash.
    $urls = implode(', ', $this->sourceUrls);
    return $urls;
  }

  /**
   * Returns the initialized data parser plugin.
   *
   * @return \Drupal\migrate_plus\DataParserPluginInterface
   *   The data parser plugin.
   */
  public function getDataParserPlugin()
  {
    if (!isset($this->dataParserPlugin)) {
      $this->dataParserPlugin = \Drupal::service('plugin.manager.metrc_migrate.data_parser')->createInstance($this->configuration['data_parser_plugin'], $this->configuration);
    }
    return $this->dataParserPlugin;
  }

  /**
   * Creates and returns a filtered Iterator over the documents.
   *
   * @return \Iterator
   *   An iterator over the documents providing source rows that match the
   *   configured item_selector.
   */
  protected function initializeIterator()
  {
    return $this->getDataParserPlugin();
  }
}

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

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