You are here

function drush_salesforce_pull_sf_pull_file in Salesforce Suite 5.0.x

Same name and namespace in other branches
  1. 8.4 modules/salesforce_pull/salesforce_pull.drush.inc \drush_salesforce_pull_sf_pull_file()
  2. 8.3 modules/salesforce_pull/salesforce_pull.drush.inc \drush_salesforce_pull_sf_pull_file()

Queues records for pull from Salesforce from the given file and mapping.

Parameters

string $file: File name with IDs.

string $name: Mapping name.

File

modules/salesforce_pull/salesforce_pull.drush.inc, line 156
Salesforce Pull drush 8 commands.

Code

function drush_salesforce_pull_sf_pull_file($file, $name = NULL) {
  _drush_salesforce_deprecated();
  if (empty($file)) {
    drush_log("File argument is required.", 'error');
    drush_log("usage:\n  drush sf-pull-file file_name [mapping_id]", 'error');
    return;
  }
  if (!file_exists($file)) {
    drush_log('File not found.', 'error');
    return;
  }
  if (!($mapping = _salesforce_drush_get_mapping($name))) {
    return;
  }

  // Fetch the base query to make sure we can pull using this mapping.
  $soql = $mapping
    ->getPullQuery([], 1, 0);
  if (empty($soql)) {
    drush_log(dt('Unable to generate pull query for !name. Does this mapping have any Salesforce Action Triggers enabled?'), 'error');
    return;
  }
  $sf = \Drupal::service('salesforce.client');
  $rows = array_map('str_getcsv', file($file));

  // Track IDs to avoid duplicates.
  $seen = [];

  // Max length for SOQL query is 20,000 characters. Chunk the IDs into smaller
  // units to avoid this limit. 1000 IDs per query * 18 chars per ID = up to
  // 18000 characters per query, plus up to 2000 for fields, where condition,
  // etc.
  $queries = [];
  foreach (array_chunk($rows, 1000) as $i => $chunk) {

    // Reset our base query:
    $soql = $mapping
      ->getPullQuery([], 1, 0);

    // Now add all the IDs to it.
    $sfids = [];
    foreach ($chunk as $j => $row) {
      if (empty($row) || empty($row[0])) {
        drush_log(dt('Skipping row !n, no SFID found.', [
          '!n' => $j,
        ]), 'warning');
        continue;
      }
      try {
        $sfid = new SFID($row[0]);

        // Sanity check to make sure the key-prefix is correct.
        // If so, this is probably a good SFID.
        // If not, it is definitely not a good SFID.
        if ($mapping
          ->getSalesforceObjectType() != $sf
          ->getObjectTypeName($sfid)) {
          throw new \Exception();
        }
      } catch (\Exception $e) {
        drush_log(dt('Skipping row !n, no SFID found.', [
          '!n' => $j,
        ]), 'warning');
        continue;
      }
      $sfid = (string) $sfid;
      if (empty($sfids[$sfid])) {
        $sfids[] = $sfid;
        $seen[$sfid] = $sfid;
      }
    }
    $soql
      ->addCondition('Id', $sfids, 'IN');
    $queries[] = $soql;
  }
  if (empty($seen)) {
    drush_log(dt('No SFIDs found in the given file.'), 'error');
    return;
  }
  if (!drush_confirm(dt('Ready to enqueue !count records for pull?', [
    '!count' => count($seen),
  ]))) {
    return;
  }
  foreach ($queries as $soql) {
    \Drupal::service('event_dispatcher')
      ->dispatch(new SalesforceQueryEvent($mapping, $soql), SalesforceEvents::PULL_QUERY);
    drush_log(dt('Issuing pull query: !query', [
      '!query' => (string) $soql,
    ]));
    $results = \Drupal::service('salesforce.client')
      ->query($soql);
    if (empty($results)) {
      drush_lo('No records found to pull.');
      continue;
    }
    \Drupal::service('salesforce_pull.queue_handler')
      ->enqueueAllResults($mapping, $results);
    drush_print(dt('Queued !count items for pull.', [
      '!count' => $results
        ->size(),
    ]));
  }
}