You are here

function private_message_update_8005 in Private Message 8.2

Migrate the records into a new table.

File

./private_message.install, line 165
Holds install and update hooks for the Private Message module.

Code

function private_message_update_8005(&$sandbox) {

  // Store last processed thread ID, so the sites with a huge amount of threads
  // will have at least some chances to complete this update in a few runs.
  $last_processed = \Drupal::state()
    ->get(PRIVATE_MESSAGE_LAST_STATE, 0);
  $database = \Drupal::database();
  if (empty($sandbox['max'])) {
    $sandbox['progress'] = 0;
    $sandbox['max'] = $database
      ->select(PRIVATE_MESSAGE_THREADS_TABLE, 't')
      ->condition('t.id', $last_processed, '>')
      ->countQuery()
      ->execute()
      ->fetchField();
  }

  // Select a range of the threads:
  $query = $database
    ->select(PRIVATE_MESSAGE_THREADS_TABLE, 't');
  $query
    ->fields('t', [
    'id',
  ]);
  $query
    ->condition('t.id', $last_processed, '>');
  $query
    ->range(0, PRIVATE_MESSAGE_UPDATE_LIMIT);
  $query
    ->orderBy('t.id');
  $threads = $query
    ->execute()
    ->fetchCol();
  if (empty($threads)) {
    $sandbox['#finished'] = 1;

    // Reset last processed thread.
    \Drupal::state()
      ->delete(PRIVATE_MESSAGE_LAST_STATE);
    $sandbox['messages'][] = t('@total threads processed.', [
      '@total' => $sandbox['max'],
    ]);
    return;
  }

  // Select the thread-member pairs:
  $query = $database
    ->select(PRIVATE_MESSAGE_THREADS_TABLE, 't');
  $query
    ->fields('t', [
    'id',
  ]);
  $query
    ->condition('t.id', $threads, 'IN');
  $query
    ->orderBy('t.id');
  $query
    ->leftJoin(PRIVATE_MESSAGE_MEMBERS_TABLE, 'm', 't.id = m.entity_id');
  $query
    ->fields('m', [
    'members_target_id',
  ]);
  $thread_member_pairs = $query
    ->execute()
    ->fetchAll();
  foreach ($thread_member_pairs as $thread_member_pair) {
    $thread_id = $thread_member_pair->id;
    $member_id = $thread_member_pair->members_target_id;

    // Get the last access timestamp of the member for thread.
    $query = $database
      ->select(PRIVATE_MESSAGE_LAST_ACCESS_TABLE, 'la');
    $query
      ->leftJoin(PRIVATE_MESSAGE_ACCESS_TIME_TABLE, 'at', 'at.id = la.last_access_time_target_id');
    $query
      ->condition('la.entity_id', $thread_id);
    $query
      ->condition('at.owner', $member_id);
    $query
      ->addExpression('MAX(at.access_time)', 'access_time');
    $access_timestamp = $query
      ->execute()
      ->fetchField() ?: 0;

    // Get the last delete timestamp of the member for thread.
    $query = $database
      ->select(PRIVATE_MESSAGE_LAST_DELETE_TABLE, 'ld');
    $query
      ->leftJoin(PRIVATE_MESSAGE_DELETE_TIME_TABLE, 'dt', 'dt.id = ld.last_delete_time_target_id');
    $query
      ->condition('ld.entity_id', $thread_id);
    $query
      ->condition('dt.owner', $member_id);
    $query
      ->addExpression('MAX(dt.delete_time)', 'delete_time');
    $delete_timestamp = $query
      ->execute()
      ->fetchField() ?: 0;
    try {

      // Update the new table with the access/delete time.
      $database
        ->insert(PRIVATE_MESSAGE_HISTORY_TABLE)
        ->fields([
        'uid' => $member_id,
        'thread_id' => $thread_id,
        'access_timestamp' => $access_timestamp,
        'delete_timestamp' => $delete_timestamp,
      ])
        ->execute();
    } catch (IntegrityConstraintViolationException $e) {

      // Just skip if row already exists.
    }
  }
  $sandbox['progress'] += count($threads);
  $sandbox['#finished'] = $sandbox['progress'] / $sandbox['max'];

  // At the end of run update the last processed thread ID.
  $last_processed = end($threads);
  \Drupal::state()
    ->set(PRIVATE_MESSAGE_LAST_STATE, $last_processed);

  // Or reset it when all the threads processed.
  if ($sandbox['#finished'] === 1) {
    \Drupal::state()
      ->delete(PRIVATE_MESSAGE_LAST_STATE);
  }
  $sandbox['messages'][] = t('@current/@total threads processed.', [
    '@count' => $sandbox['progress'],
    '@total' => $sandbox['max'],
  ]);
}