<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Goran Nikolovski</title>
    <description>The latest articles on Forem by Goran Nikolovski (@gnikolovski).</description>
    <link>https://forem.com/gnikolovski</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F418755%2Fd0563856-8ad0-4ae9-a42d-91f1cf249334.jpeg</url>
      <title>Forem: Goran Nikolovski</title>
      <link>https://forem.com/gnikolovski</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/gnikolovski"/>
    <language>en</language>
    <item>
      <title>4 cool new PHP 8 features</title>
      <dc:creator>Goran Nikolovski</dc:creator>
      <pubDate>Sun, 16 Aug 2020 13:40:15 +0000</pubDate>
      <link>https://forem.com/gnikolovski/4-cool-new-php-8-features-14kl</link>
      <guid>https://forem.com/gnikolovski/4-cool-new-php-8-features-14kl</guid>
      <description>&lt;p&gt;PHP 8 will be released in a little over three months, to be exact on November 26, 2020. It's a new major version of one of the most popular languages used in web development. The new version means some breaking changes, but also lots of new features and performance/security improvements. Here are 4 cool new features that I can't wait to use in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Named arguments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When we pass arguments to a function, we are doing it based on the parameter position. Named arguments allow passing arguments to a function based on the name. This is a good thing because we don't have to remember the argument position anymore and it will also be much easier to skip default values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Positional arguments.
$pieces = explode('-', 'piece1-piece2-piece3');

// Named arguments.
$pieces = explode(delimiter: '-', string: 'piece1-piece2-piece3');
// or
$pieces = explode(string: 'piece1-piece2-piece3', delimiter: '-');
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The old way of passing arguments will still work, so if this is not something you like you don't have to use it. Some IDEs like PHPStorm already provide hints for argument names, but having this in PHP core is a cool thing if you ask me.&lt;/p&gt;

&lt;p&gt;For more information see &lt;a href="https://wiki.php.net/rfc/named_params"&gt;PHP RFC: Named Arguments&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Nullsafe operator ?-&amp;gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I really like this feature. It will cut the number of lines of code that I have to write especially when accessing some deeply nested fields in Drupal. It's a common thing to call a method on the result of an expression if it's not NULL. This usually leads to a deeply nested code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$street_number =  null;

$current_user = \Drupal::currentUser();

if ($current_user !== NULL) {
    $account = $current_user-&amp;gt;getAccount();

    if ($account !== NULL) {
        $address = $account-&amp;gt;getAddress();

        if ($address !== NULL) {
            $street_number = $address-&amp;gt;getStreetNumber();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That is a lot of lines of code just to get the street number. With the Nullsafe operator we can write this in just ONE line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$street_number = \Drupal::currentUser()?-&amp;gt;getAccount()?-&amp;gt;getAddress()?-&amp;gt;getStreetNumber();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For more information see &lt;a href="https://wiki.php.net/rfc/nullsafe_operator"&gt;PHP RFC: Nullsafe operator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. String contains, string starts with and string ends with functions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, I don't have to use strpos() function anymore to check if a string contains another string. I waited for this function for a very long time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (strpos('DS9 centers on the formerly Cardassian', 'formerly') !== false) {}

// vs.

if (str_contains('DS9 centers on the formerly Cardassian', 'formerly')) {}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Checking if a string starts or ends with another string is also a welcome addition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;str_starts_with('Bajoran', 'Baj'); // returns TRUE 
str_ends_with('Bajoran', 'oran'); // returns TRUE
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For more information see &lt;a href="https://wiki.php.net/rfc/str_contains"&gt;PHP RFC: str_contains&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For more information see &lt;a href="https://wiki.php.net/rfc/add_str_starts_with_and_ends_with_functions"&gt;PHP RFC: Add str_starts_with() and str_ends_with() functions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Constructor property promotion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This sounds complicated, but it isn't. This feature will eliminate boilerplate and that is a cool thing. Constructor property promotion is combining class properties and the class constructor. This feature already exists in Hack -- language created by Facebook that is considered as a dialect of PHP. Let's see how this works. Currently, in PHP 7 we have to do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Human {
    public float $height;
    public float $weight;
    public integer $years;

    public function __construct(
        float $height = 0.0,
        float $weight = 0.0,
        integer $years = 0,
    ) {
        $this-&amp;gt;height = $height;
        $this-&amp;gt;weight = $weight;
        $this-&amp;gt;years = $years;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And the new shorthand syntax in PHP 8:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Human {
    public function __construct(
        public float $height = 0.0,
        public float $weight = 0.0,
        public integer $years = 0,
    ) {}
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For more information see &lt;a href="https://wiki.php.net/rfc/constructor_promotion"&gt;PHP RFC: Constructor Property Promotion&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you like this article, you can &lt;a href="https://twitter.com/_gnikolovski"&gt;follow me on Twitter&lt;/a&gt; for more quality content in the future.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>php8</category>
      <category>php</category>
    </item>
    <item>
      <title>How to convert existing image fields into Media images - Drupal</title>
      <dc:creator>Goran Nikolovski</dc:creator>
      <pubDate>Tue, 04 Aug 2020 18:30:05 +0000</pubDate>
      <link>https://forem.com/gnikolovski/how-to-convert-existing-image-fields-into-media-images-drupal-28a3</link>
      <guid>https://forem.com/gnikolovski/how-to-convert-existing-image-fields-into-media-images-drupal-28a3</guid>
      <description>&lt;p&gt;&lt;em&gt;All my articles are first published and hosted on my &lt;a href="https://gorannikolovski.com/"&gt;blog&lt;/a&gt; - you can find this article &lt;a href="https://gorannikolovski.com/blog/how-convert-existing-image-fields-media-images"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Converting existing image fields to Media image fields is easier than you might think. I just converted all image fields to Media image fields on this website and in this article, I'll show you how I did it.&lt;/p&gt;

&lt;p&gt;I created this website about four years ago, and at the time Media wasn't in the core. I used regular image fields to store images in my content types and paragraphs.&lt;/p&gt;

&lt;p&gt;While there is nothing wrong with regular image fields, using Media is much better at least from the content editing perspective. UI looks much better and you can re-use existing images, and that isn't the case with image fields.&lt;/p&gt;

&lt;p&gt;I mean look at the Media library modal window. Isn't that cool? You see all your existing Media images, and you can re-use them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yWp8Zy1q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n399upxu5y59iydw3xw3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yWp8Zy1q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n399upxu5y59iydw3xw3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, here is how I migrated from regular images to Media images.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Enable modules&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The very first step you have to do is to enable Media and Media Library modules. These modules are not enabled by default. Once enabled, you'll see several Media types. In this case, we care only about the Image media type, so if you don't need them you can delete other media types.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Create media image fields&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For each image field create a media image counterpart. For example, my Article content type has the Social share image field, so I created the Social share image media field.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ftwh4hdZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rnjqml0ma7a0w63nfmpe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ftwh4hdZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rnjqml0ma7a0w63nfmpe.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see in the screenshot, Social share image media is an entity reference field. And the settings for this field look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q59bNiD0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jk6einy21vnpqyofjo3g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q59bNiD0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jk6einy21vnpqyofjo3g.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Create and attach Media entities&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, comes the fun part. We get to write some code.&lt;/p&gt;

&lt;p&gt;Image field holds the reference to file entities. We just need to create Media entities and attach those existing file entities. This is how I did it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;gn_core_update_8001&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;$sandbox&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;$entity_types&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'node'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'paragraph'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="nv"&gt;$image_fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'field_image'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'field_social_share_image'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$entity_types&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$entity_type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$entities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;\Drupal&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;entityTypeManager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;getStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$entity_type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;loadMultiple&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$image_fields&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$image_field&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;gn_core_migrate_to_media&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$entities&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$image_field&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;gn_core_migrate_to_media&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$entities&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$image_field&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;$image_media_field_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$image_field&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'_media'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$entities&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nv"&gt;$entity&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;hasField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$image_field&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="nv"&gt;$entity&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$image_field&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;FALSE&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="nv"&gt;$entity&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;hasField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$image_media_field_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;$images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$entity&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$image_field&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nv"&gt;$entity&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$image_media_field_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$images&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$media&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;\Drupal&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;entityTypeManager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
          &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;getStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'media'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="s1"&gt;'bundle'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'image'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'uid'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="nv"&gt;$media&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'field_media_image'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$image&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$media&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$entity&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$image_media_field_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;appendItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$media&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nv"&gt;$entity&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The code is pretty much self-explanatory. I'm looping through all node and paragraph entities, checking if image fields called field_image and field_social_share_image exist and they aren't empty and then creating a Media entity with a reference to existing file entities. The last thing is to attach those Media entities to nodes and paragraphs.&lt;/p&gt;

&lt;p&gt;I added this code to an update hook in my custom GN Core module, but you can also use something like Devel execute PHP if you don't want to use update hooks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Final adjustments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The last step is to check all your custom Twig templates and Sass/CSS files and adjust them if needed. Also, if you are using images as tokens you need to update those as well. In my case, I'm using the Social share image media field for the Open Graph image tag.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KX_ZnxDM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/blw094dv810fo3rvolon.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KX_ZnxDM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/blw094dv810fo3rvolon.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, I had to update the token for that field from this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[node:field_social_share_image:entity:url]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;to this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[node:field_social_share_image_media:entity:field_media_image:entity:url]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After you are completely sure that everything works fine, you can delete your old image fields.&lt;/p&gt;

&lt;p&gt;And that's it. I told you it isn't that complicated.&lt;/p&gt;

</description>
      <category>drupal</category>
      <category>media</category>
      <category>migrate</category>
      <category>image</category>
    </item>
  </channel>
</rss>
