0

I'm trying to import user profile pictures from Drupal 7 to Drupal 8. So far I've managed to upload the picture from the url and save it to the file system, create Media entity and use the user id as author. However, the picture doesn't show to the user profile (Manage Form Display), neither to the Edit Media Content Type page.

Here is the code I have so far:

$values = array(
      'name' => $user["name"],
      'pass' => [
         'value' => $user["pass"],
         'pre_hashed' => TRUE,
      ],
      'status' => $user["status"],
      'mail' => $user["mail"],
      'field_first_name' => $user["field_first_name"],
      'field_last_name' => $user["field_last_name"],
);

$userStorage = \Drupal::entityTypeManager()->getStorage('user');
$userEntity = $userStorage->create($values);

    $replaced = str_replace("\\", "", $user["picture"]);
    $imageData = file_get_contents($replaced);
    $fileName = basename($replaced);
    $file = file_save_data(
        $imageData, 
        "public://". $fileName, 
        FileSystemInterface::EXISTS_RENAME
    );
    
    $media = Media::create([
        'bundle' => 'image',
        'uid' => $userEntity->id(),
        'langcode' => \Drupal::languageManager()->getDefaultLanguage()->getId(),
        'field_media_file' => [
             'target_id' => $file->id(),
             'alt' => $file->getFilename(),
        ],
        'thumbnail' => [
             'target_id' => $file->id(),
             'alt' => $file->getFilename(),
        ],
    ]);
    
    $media->setName($fileName)->setPublished(TRUE)->save();
   
    $userEntity->field_user_picture->appendItem($media);

Is the something missing in the code?

UPDATE

I noticed (as also pointed out in the comments) $userEntity->save(); is missing after $userEntity->field_user_picture->appendItem($media);.

However, after I added that line, I get the following error:

Error: Call to undefined method Drupal\media\Entity\Media::getFileUri() in Drupal\image\Plugin\Field\FieldType\ImageItem->preSave() (line 321 of /var/www/html/web/core/modules/image/src/Plugin/Field/FieldType/ImageItem.php) #0 /var/www/html/web/core/lib/Drupal/Core/Field/FieldItemList.php(233): Drupal\image\Plugin\Field\FieldType\ImageItem->preSave()

Is it related to file_save_data() function?

3
  • 1
    First, I would be using Migrate for this. Second, I don't see you saving the user object. Is appendItem the proper method to use for adding a field value? If the field doesn't show on Manage Form Display, was it even created correctly?
    – Kevin
    Commented Jan 24, 2021 at 16:50
  • @Kevin appendItem looks valid, the core FileUpload class uses the same method to append a file entity
    – Clive
    Commented Jan 24, 2021 at 19:24
  • Hi! I wrote down some updates on the question. @Kevin was right, $userEntity->save(); was missing.
    – DamianFox
    Commented Jan 25, 2021 at 20:52

1 Answer 1

1

I've found the solution.
I don't need to create a Media entity and append it to the User entity, since the profile picture field type is Image, so I just need to add the file->id() to the specific field.
Here is the code:

$replaced = str_replace("\\", "", $user["picture"]);
$imageData = file_get_contents($replaced);
$fileName = basename($replaced);
$file = file_save_data(
      $imageData, 
      "public://". $fileName, 
      FileSystemInterface::EXISTS_RENAME
);

$values = array(
      'name' => $user["name"],
      'pass' => [
         'value' => $user["pass"],
         'pre_hashed' => TRUE,
      ],
      'field_user_picture' => array('target_id' =>$file->id()),
      'status' => $user["status"],
      'mail' => $user["mail"],
      'field_first_name' => $user["field_first_name"],
      'field_last_name' => $user["field_last_name"],
);

$userStorage = \Drupal::entityTypeManager()->getStorage('user');
$userEntity = $userStorage->create($values);

Then, if required, I can create the Media entity as following:

$media = Media::create([
          'bundle' => 'image',
          'uid' => $userEntity->id(),
          'langcode' => \Drupal::languageManager()->getDefaultLanguage()->getId(),
          'field_media_image' => [
             'target_id' => $file->id(),
             'alt' => $file->getFilename(),
          ],
          'thumbnail' => [
             'target_id' => $file->id(),
             'alt' => $file->getFilename(),
          ],
]);

$media->setName($fileName)->setPublished(TRUE)->save();
1
  • Thanks. This just helped. For some reason, entity/media rest endpoint always throws 422. I ended up building my own resource using your code. Commented Jun 15, 2022 at 12:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.