I am trying to import some videos into a 8.0.5 site (yes, I know I should upgrade) I have over 200 videos that neeed to be imported into their own individual node. It seems like a perfect opportunity to get my head around the batch api.

After getting all the videos as objects in a sigle array, I then chunk this into batches of 10 using array_chunk() and then set each chunk as its own opperation.

I would have thought that the batch api would have sent each data array as a signle array to my process function. However, it seems that only the first video from each batch is getting processed.

If I add the &$context variable to my process function and dump it out, it just shows me the next object.

Please, can anyone point out what I have done wrong? :(

public function batchStart() {

ini_set('max_execution_time', 0);
$directory = drupal_get_path('module', 'drp_broadcast_videos_importer') . '/broadcast-videos';
$videoImporter = new VideoImporterController();
$videosArray = $videoImporter->getVideosFromDirectory($directory);
// Chunk up the array.
$videoChunks = array_chunk($videosArray, 5);

foreach ($videoChunks as $chunk) {
  $operations[] = [
    '\Drupal\drp_broadcast_videos_importer\Controller\ImportController::processBatch',
    $chunk,
  ];
}

$batch = [
  'title' => t('Processing Batch'),
  'operations' => $operations,
  'finished' => '\Drupal\drp_broadcast_videos_importer\Controller\ImportController::finishedBatch',
  'init_message' => t('Batch is starting.'),
  'progress_message' => t('Processed @current out of @total.'),
  'error_message' => t('Batch has encountered an error.'),
];

batch_set($batch);

return batch_process('/');
}


static function processBatch($video, $context) {
  try {
    $file = (new VideoImporterController())->createNewFileEntity($video->video, $video->filename);

    $broadcastNode = Node::create(['type' => 'broadcast_video']);
    $broadcastNode->setTitle($video->title);
    $broadcastNode->setOwnerId(\Drupal::currentUser()->id());
    $broadcastNode->setCreatedTime($video->date);
    $broadcastNode->set('field_broadcast_pack_name', $video->pack);
    $broadcastNode->set('field_videos', ['target_id' => $file->id()]);
    $broadcastNode->save();

    $context['message'] = $video->title . ' processed.';
    $context['results'][] = $video->id;

  }
  catch (EntityStorageException $exception) {
//              \Drupal::logger('broadcast_videos_importer')
 //                ->error($this
//                  ->t(
//                    'The broadcast video @title could not be uploaded',
//                    ["@title" => $videoObject->title]
//                  )
//                );
//              drupal_set_message($this->t(
//                'The broadcast video @title could not be uploaded',
//                ["@title" => $videoObject->title]));
    }
  return $broadcastNode->id();
 }
有帮助吗?

解决方案

$operations[] = [
  '\Drupal\drp_broadcast_videos_importer\Controller\ImportController::processBatch',
  $chunk,
];

In the above, $chunk is the list of parameters that will be passed to the batch process method. So if $chunk is an array of 5 videos, your method signature would need to look like this to match.

static function processBatch($video1, $video2, $video3, $video4, $video5, &$context) {

That's probably not what you're hoping for. To fix, just wrap $chunk in array:

$operations[] = [
  '\Drupal\drp_broadcast_videos_importer\Controller\ImportController::processBatch',
  [$chunk],
];

Now your process method signature looks like this:

static function processBatch($videos, &$context) {

And you just need to loop through the videos in each operation.

许可以下: CC-BY-SA归因
scroll top