Q:

Set image as permanent in custom block plugin, temporary URI

I'm building a custom block plugin with an image upload which is working fine except for the fact that although the $file->status is set to permanent the URI still comes up as temporary.
This is the code I'm using:
namespace Drupal\eight\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\file\Entity\File;
use Drupal\image\Entity\ImageStyle;

class MyBlock extends BlockBase {
  public function defaultConfiguration() {
    return [
      'upload_image' => '',
    ] + parent::defaultConfiguration();
  }

  public function blockForm($form, FormStateInterface $form_state) {
    $form['upload_image'] = [
      '#type' => 'managed_file',
      '#title' => $this->t('Upload Image'),
      '#default_value' => $this->configuration['upload_image'],
    ];

    return $form;
  }

  public function saveImage($fid) {
    $file = File::load( $fid );
    if ($file) {
      $file->setPermanent();
      $file->save();
    }
  }

  public function blockSubmit($form, FormStateInterface $form_state) {
    $fid = $form_state->getValue('upload_image')[0];
    $this->saveImage($fid);

    $this->configuration['upload_image'] = [$fid];
  }

  public function build() {
    $config = $this->getConfiguration();
    $image = '';

    $file = File::load($config['upload_image'][0]);
    if ($file) {
      return [
        'logo' => $file->getFileUri(),
      ];
    } else {
      return [];
    }
  }
}

Inspecting the $file object before and after the saveImage method the status is actually changing from 0 to 1 but the URI I get is still pointing to the temporary file scheme.
URI: temporary://xxxxx.jpg
URL: xxxxx.xxx/system/temporary?file=xxxxx.JPG
What would be the way to correctly store the image as permanent?

A:

To set the correct file scheme is necessary to define the upload location in the form array.
I've amended the form as follows:
public function blockForm($form, FormStateInterface $form_state) {
  $form['upload_image'] = [
    '#type' => 'managed_file',
    '#title' => $this->t('Upload Image'),
    '#default_value' => $this->configuration['upload_image'],
    '#upload_location => 'public://blocks',
    ];

  return $form;
}

The URI and URL are now as expected and the file is permanently saved.

