I found the answer. One thing weird is that you have to go to the parent entity and from this point go back to the field, only then you can get the url.
function mytheme_preprocess_field(&$variables){
if($variables['field_name'] == 'field_banner_image'){
/** @var \Drupal\image\Plugin\Field\FieldType\ImageItem $field */
$field = $variables['element']['#items'][0];
$field_image_url = get_image_uri($field->getEntity(), 'field_banner_image');
$variables['banner_url'] = file_create_url($field_image_url);
}
}
with
/**
* Get the set or default image uri for a file image field (if either
* exist).
* @param $entity
* @param $fieldName
* @return null|string
*/
function get_image_uri($entity, $fieldName){
$image_uri = NULL;
if($entity->hasField($fieldName)){
try{
$field = $entity->{$fieldName}; // Try loading from field values first.
if($field && $field->target_id){
$file = \Drupal\file\Entity\File::load($field->target_id);
if($file){
$image_uri = $file->getFileUri();
}
}
} catch(\Exception $e){
\Drupal::logger('get_image_uri')->notice($e->getMessage(), []);
}
// If a set value above wasn't found, try the default image.
if(is_null($image_uri)){
try{
$field = $entity->get($fieldName); // Loading from field definition
if($field){
// From the image module /core/modules/image/ImageFormatterBase.php
// $default_image = $test->fieldDefinition->getFieldStorageDefinition()->getSetting('default_image');
$default_image = $field->getSetting('default_image');
if($default_image && $default_image['uuid']){
// $defaultImageFile = \Drupal::entityManager()->loadEntityByUuid('file', $default_image['uuid']));
// See https://www.drupal.org/node/2549139 entityManager is deprecated.
// Use entity.repository instead.
$entityrepository = Drupal::service('entity.repository');
$defaultImageFile = $entityrepository->loadEntityByUuid('file', $default_image['uuid']);
if($defaultImageFile){
$image_uri = $defaultImageFile->getFileUri();
}
}
}
} catch(\Exception $e){
\Drupal::logger('get_image_uri')->notice($e->getMessage(), []);
}
}
}
return $image_uri;
}
Also another weird thing I noticed while trying stuff:
$field->entity
and
$field->getEntity()
does not give the same object
\Drupal\image\Plugin\Field\FieldType\ImageItem
with$field = $variables['element']['#items'][0];
but$field
doesn't have the method getFileUri!