public function submitForm(array &$form, FormStateInterface $form_state) {
    // Process image cropping data.
    $form_state_values = $form_state->getValues();
    $fid = $form_state_values['fid'];
    if (\Drupal::moduleHandler()->moduleExists('image_widget_crop') && isset($form_state_values['image_crop'])) {
      $entity = \Drupal\file\Entity\File::Load($fid);
      if ($entity && is_array($form_state_values['image_crop']) && isset($form_state_values['image_crop']['crop_wrapper'])) {
        $this->submitFormCrops($form, $form_state, $form_state_values, $entity);
      }
    }
    // Save other image data.
    if (!empty($form_state_values['del'])) {
      if ($form_state->getValue('cover_fid') == $fid) {
        db_update('photos_album')
          ->fields(array(
            'fid' => 0
          ))
          ->condition('pid', $form_state->getValue('oldpid'))
          ->execute();
      }
      $msg = photos_file_del($fid, $form_state_values['filepath']);
      $uid = $form_state_values['uid'];
    }
    else {
      $wid = is_numeric($form_state_values['wid']) ? $form_state_values['wid'] : 0;
      db_update('photos_image')
        ->fields(array(
          'pid' => $form_state_values['pid'],
          'des' => $form_state_values['des'],
          'wid' => $wid
        ))
        ->condition('fid', $fid)
        ->execute();

      if ($form_state_values['title'] <> $form_state_values['oldtitle']) {
        db_update('photos_image')
          ->fields(array(
            'title' => $form_state_values['title']
          ))
          ->condition('fid', $fid)
          ->execute();
      }
      if ($form_state_values['pid'] <> $form_state->getValue('oldpid')) {
        $sub_select = db_select('photos_comment', 'v')
          ->fields('v', array('cid'))
          ->condition('v.fid', $fid)
          ->execute()->fetchCol();
        if (!empty($sub_select)) {
          db_update('comment')
            ->fields(array(
              'nid' => $form_state_values['pid']
            ))
            ->condition('cid', $sub_select, 'IN')
            ->execute();
        }
        $pid = $form_state_values['pid'];
        $uid = $form_state_values['uid'];
      }
    }
    // Clear image page cache.
    Cache::invalidateTags(array('photos:image:' . $fid));
    if ($nid = $form_state->getValue('nid')) {
      // Clear album page and node cache.
      Cache::invalidateTags(array('photos:album:' . $nid, 'node:' . $nid));
    }

    if (isset($pid) && $pid) {
      $pid;
      // @todo if image moved to new album also move attached comments to new node?
      // Get node object and update comment statistics.
      // @todo Argument 1 passed to Drupal\comment\CommentStatistics::update() must be an instance of Drupal\comment\CommentInterface.
      // $node = \Drupal\node\Entity\Node::load($nid);
      // \Drupal::service('comment.statistics')->update($node);
      photos_set_count('node_album', $pid);
      // Clear album page and node cache.
      Cache::invalidateTags(array('photos:album:' . $pid, 'node:' . $pid));
      photos_set_count('user_image', $uid);
    }

    // Image deleted or moved.
    if (isset($msg)) {
      $pid = $form_state->getValue('oldpid');
      drupal_set_message(t('Image deleted.'));
      // Redirect to album page.
      $nid = $form_state->getValue('nid');
      $url = Url::fromUri('base:photos/album/' . $nid);
      $form_state->setRedirectUrl($url);
    }
    // @todo redirect to image page?
    // @todo redirect to destination.
    drupal_set_message(t('Changes saved.'));


  // @todo check and implement the following for sub-albums.
  /*
    foreach ($form_state->getValue('photos') as $fid => $form_state_values) {
     if (!empty($form_state_values['del'])) {
       $msg[] = db_query('DELETE FROM {photos_node} WHERE fid = :fid AND nid = :nid',
         array(':fid' => $fid, ':nid' => $form_state->getValue('nid')));
     }
     else {
       $update_fields = array(
         'des' => $form_state_values['des'],
       );
       if ($form_state_values['title'] <> $form_state_values['oldtitle']) {
         $update_fields['title'] = $form_state_values['title'];
       }
       db_merge('photos_image')
         ->key(array(
           'fid' => $fid
         ))
         ->fields($update_fields)
         ->execute();
       if ($form_state_values['wid']) {
         db_update('photos_node')
           ->fields(array(
             'wid' => $form_state_values['wid']
           ))
           ->condition('fid', $fid)
           ->condition('nid', $form_state->getValue('nid'))
           ->execute();
       }
     }
   }
   if (isset($msg)) {
     photos_set_count('node_node', $form_state->getValue('nid'));
     drupal_set_message(t('@count images are move out.', array('@count' => count($msg))));
   }
   */

  }
  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $fid = $this->id;
    $pid = db_query("SELECT pid FROM {photos_image} WHERE fid = :fid", array(':fid' => $fid))->fetchField();
    // Get album type.
    $type = $form_state->getValue('type');

    if ($type <> 'sub_album') {
      // Remove from search index.
      if (\Drupal::moduleHandler()->moduleExists('search')) {
        search_index_clear('photos', $fid);
      }
      // Delete image.
      $v = photos_file_del($fid, 0, 1);
      // Update album count.
      if (isset($_GET['pid']) && intval($_GET['pid']) == $_GET['pid']) photos_set_count('node_album', $_GET['pid']);
      if (isset($_GET['uid']) && intval($_GET['uid']) == $_GET['uid']) photos_set_count('user_image', $_GET['uid']);
    }
    else {
      // Remove from sub-album.
      $v = db_delete('photos_node')
        ->condition('fid', $fid)
        ->execute();
      // Update sub-album count.
      if (isset($_GET['nid']) && intval($_GET['nid']) == $_GET['nid']) photos_set_count('node_node', $_GET['nid']);
    }
    if ($v) {
      drupal_set_message(t('Image deleted.'));
      // Invalidate cache tags.
      Cache::invalidateTags(array('node:' . $pid, 'photos:album:' . $pid, 'photos:image:' . $fid));
      // @todo redirect to album or sub-album.
      $url = Url::fromUri('base:photos/album/' . $pid);
      $form_state->setRedirectUrl($url);
    }
    else {
      drupal_set_message(t('Delete failed.'));
      // Redirect to cancel URL.
      $form_state->setRedirectUrl($this->getCancelUrl());
    }
  }