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
    Jan 24, 2021 at 16:50
  • @Kevin appendItem looks valid, the core FileUpload class uses the same method to append a file entity
    – Clive
    Jan 24, 2021 at 19:24
  • Hi! I wrote down some updates on the question. @Kevin was right, $userEntity->save(); was missing.
    – DamianFox
    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. Jun 15, 2022 at 12:46

Your Answer

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

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