# Problems to update a files field with an image

**URL:** <https://forum.getkirby.com/t/problems-to-update-a-files-field-with-an-image/33940>\
**Category:** Questions\
**Tags:** v4\
**Created:** [April 12, 2025, 8:16pm UTC](https://forum.getkirby.com/t/problems-to-update-a-files-field-with-an-image/33940 "2025-04-12T20:16:39Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![JanStieler](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/janstieler/32/15642_2.png) [@JanStieler](https://forum.getkirby.com/u/JanStieler)\
**Post date:** [April 12, 2025, 8:16pm UTC](https://forum.getkirby.com/t/problems-to-update-a-files-field-with-an-image/33940/1 "2025-04-12T20:16:39Z")

</div>

Hello,

I try to scrap a json file and CLI import as pages in Kirby V4.  
the import works like a charme but I have a problem to fill a files field with an image.

```php
 foreach($news['images'] as $newsImageURL){
                    // cURL verwenden, um nur die HTTP-Header zu erhalten
                    $newsImageDownload = curl_init($newsImageURL);
                    curl_setopt($newsImageDownload, CURLOPT_RETURNTRANSFER, true);
                    $newsImageData = curl_exec($newsImageDownload);

                    // Hole den HTTP-Header
                    curl_close($newsImageDownload); 

                    if ($newsImageData === false) {
                        $cli->dump('Fehler beim Abrufen des Bildes.');
                        continue;
                    }

                    $tempFile = tempnam(sys_get_temp_dir(), 'img');
                    file_put_contents($tempFile, $newsImageData);

                    // MIME-Typ mit finfo_file() ermitteln
                    $finfo = finfo_open(FILEINFO_MIME_TYPE);
                    $mimeType = finfo_file($finfo, $tempFile);
                    finfo_close($finfo);

                    // Extrahiere den MIME-Typ aus den HTTP-Headern
                    function getExtensionFromMimeType($mimeType) {
                        $mimeTypes = [
                            'image/jpeg' => 'jpg',
                            'image/png' => 'png',
                            'image/gif' => 'gif',
                            'image/webp' => 'webp',
                            'image/svg+xml' => 'svg',
                            'image/bmp' => 'bmp',
                            'image/tiff' => 'tiff',
                        ];

                        return isset($mimeTypes[$mimeType]) ? $mimeTypes[$mimeType] : 'jpg'; // Standard auf jpg setzen
                    }

                    $newsImageFiletype = getExtensionFromMimeType($mimeType);

                    try{
                        $imageCreation = File::create([
                            'source' => $tempFile,
                            'parent' => $newsEntry, 
                            'filename' => $newsAuthorName.'-'.$news['postedAtISO'].'_'.$n.'.'.$newsImageFiletype
                        ]);

                        // Überprüfen, ob das Bild erfolgreich erstellt wurde
                        if (!$imageCreation) {
                            $cli->dump('Fehler beim Erstellen des Bildes.');
                            continue;
                        }

                        $cli->dump($imageCreation);

                        $n++;

                        $newsEntry->update([
                           'newsarticleheaderimage'	=> $imageCreation->filename(),
                        ]);

                        // Temporäre Datei löschen
                        unlink($tempFile);

                    } catch (Exception $e) {
                        $cli->dump('Fehler beim Erstellen der Datei: ' . $e->getMessage());
                        continue;
                    }
                }

```

```yml
          newsarticleheaderimage:
            label: Headerimage for the Newsarticle
            type: files
            multiple: false
            layout: cards
            query: page.images

```

I have also tried to use `$imageCreation->url()`or `[$imageCreation]`. The image is in the created page folder but will not be added to the field in the page txt file.

What did I wrong?

Best

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [April 12, 2025, 8:31pm UTC](https://forum.getkirby.com/t/problems-to-update-a-files-field-with-an-image/33940/2 "2025-04-12T20:31:01Z")

</div>

You need to store the files as array, ie. either the file id or the file uuid (by default, the files field stores the uuids).

---

<div class="post-metadata">

**Author:** ![JanStieler](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/janstieler/32/15642_2.png) [@JanStieler](https://forum.getkirby.com/u/JanStieler)\
**Post date:** [April 12, 2025, 9:02pm UTC](https://forum.getkirby.com/t/problems-to-update-a-files-field-with-an-image/33940/3 "2025-04-12T21:02:25Z")

</div>

Thanks for your answer.  
I used now `['newsarticleheaderimage' => $imageCreation->uuid()]`but now I have to different UUIDs. The one which is printen inside the field is another than which is printed in the image txt file. Could it be that I recreate the image on the $imageCreation call in the fieldupdate. So that I have a new object?

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [April 13, 2025, 12:24pm UTC](https://forum.getkirby.com/t/problems-to-update-a-files-field-with-an-image/33940/4 "2025-04-13T12:24:54Z")

</div>

If the file already exists, the uuid should not be recreated. However, instead of passing the uuid object, you need to convert to string, i.e. `$file->uuid()->toString()`.

---

<div class="post-metadata">

**Author:** ![JanStieler](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/janstieler/32/15642_2.png) [@JanStieler](https://forum.getkirby.com/u/JanStieler)\
**Post date:** [April 13, 2025, 7:27pm UTC](https://forum.getkirby.com/t/problems-to-update-a-files-field-with-an-image/33940/5 "2025-04-13T19:27:35Z")

</div>

The file doesn’t exist before. It was only a idea why I got two different uuids.  
The `toString()`change also nothing.

And agin the complete CLI importscript. The break on the end is there only for development.  
The imageimport is at the end of the script. Hopefull someone see something or had an Idea whats my mistake is.

```php
<?php

return [
	'description' => 'Import Linkedin News',
	'args' => [],
	'command' => static function ($cli): void {
        $jsonurl = $cli->prompt('Please enter a json url:');
        $kirby = $cli->kirby();
        $kirby->impersonate('kirby');

        //$jsonfile = 'dataset.json';
        //$json = Json::read($jsonfile);
        
        $json = Remote::get($jsonurl)->json();
        //$cli->dump($json); exit;

        $newsPages = $kirby->page('news');
               
        foreach($json as $news){
            //finetuning output content
            $newsAuthorName = str_replace(' ','', strtolower($news['authorName']));
            $creationDate = date('Y-m-d', strtotime($news['postedAtISO']));
            $link = '(link: '. $news['url'] .' text: › Linkedin Reference target: _blank rel: nofollow)';
            
            //linkedin Hashtags aus dem Text löschen
            $newsText = preg_replace('/\s?#\w+/', '', $news['text']);

            //Generate Tags Array
            $nameArray = [$news['author']['name'],$news['author']['universalName']];

            preg_match_all('/#\w+/', $news['text'], $hashes);

            $hashesWithout = array_map(function($tag) {
                return ltrim($tag, '#');
            }, $hashes[0]);

            $allTags = array_merge($hashesWithout, $nameArray);
            $allTagsLower = array_map('strtolower', $allTags);
            $newsTagsArray = array_unique($allTagsLower);
            $newsTags = implode(', ', $newsTagsArray);

            //build the pageObject
            $newsEntry = $newsPages->createChild([
                'slug' => $newsAuthorName.'-'.$news['postedAtISO'],
                'draft' => false,
                'template' => 'news-article',
                'content' => [
                    'title' => 'Linkedin News from '.$news['authorName'] . ' on ' .$creationDate,
                    //'newsarticleheaderimage' => $newsImage[0],
                    'newsarticleheaderimage' => '',
                    'newsarticletags' => $newsTags, 
                    'date' => $creationDate,
                    'newsarticleauthor' => '',
                    'newsarticletext' => $newsText . $link,
                    'loginpage' => 'true',
                    'setallowedroles' => 'Admin, Investors', 
                    'logintarget' => '',
                    'titleoverride' => '', 
                    'showshare' => 'true',
                    'showfooterdivider' => 'false',
                    'startwhitenav' => 'false',
                ]
            ]);

            $n = 1;

            foreach($news['images'] as $newsImageURL){
                // cURL verwenden, um nur die HTTP-Header zu erhalten
                $newsImageDownload = curl_init($newsImageURL);
                curl_setopt($newsImageDownload, CURLOPT_RETURNTRANSFER, true);
                $newsImageData = curl_exec($newsImageDownload);

                // Hole die HTTP-Header
                curl_close($newsImageDownload); 

                if ($newsImageData === false) {
                    $cli->dump('Fehler beim Abrufen des Bildes.');
                    continue;
                }

                $tempFile = tempnam(sys_get_temp_dir(), 'img');
                file_put_contents($tempFile, $newsImageData);

                // MIME-Typ mit finfo_file() ermitteln
                $finfo = finfo_open(FILEINFO_MIME_TYPE);
                $mimeType = finfo_file($finfo, $tempFile);
                finfo_close($finfo);

                // Extrahiere den MIME-Typ aus den HTTP-Headern
                function getExtensionFromMimeType($mimeType) {
                    $mimeTypes = [
                        'image/jpeg' => 'jpg',
                        'image/png' => 'png',
                        'image/gif' => 'gif',
                        'image/webp' => 'webp',
                        'image/svg+xml' => 'svg',
                        'image/bmp' => 'bmp',
                        'image/tiff' => 'tiff',
                    ];

                    return isset($mimeTypes[$mimeType]) ? $mimeTypes[$mimeType] : 'jpg'; // Standard auf jpg setzen
                }

                $newsImageFiletype = getExtensionFromMimeType($mimeType);

                try{
                    $imageCreation = File::create([
                        'source' => $tempFile,
                        'parent' => $newsEntry, 
                        'filename' => $newsAuthorName.'-'.$news['postedAtISO'].'_'.$n.'.'.$newsImageFiletype
                    ]);

                    // Überprüfen, ob das Bild erfolgreich erstellt wurde
                    if (!$imageCreation) {
                        $cli->dump('Fehler beim Erstellen des Bildes.');
                        continue;
                    }

                    $newsEntry->update([
                       'newsarticleheaderimage'	=> [$imageCreation->uuid()->toString()],
                    ]);

                    // Temporäre Datei löschen
                    unlink($tempFile);

                    $n++;

                } catch (Exception $e) {
                    $cli->dump('Fehler beim Erstellen der Datei: ' . $e->getMessage());
                    continue;
                }
            }

            break;
        }

        $cli->success('linkedin News imported!');
    }
];

```

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [April 13, 2025, 7:48pm UTC](https://forum.getkirby.com/t/problems-to-update-a-files-field-with-an-image/33940/6 "2025-04-13T19:48:04Z")

</div>

Hm, you are updating one page with possibly multiple images, but the way you do it, every new image file will overwrite the value in the files field with the latest value. So to make this work properly with multiple images, you would have to merge the existing values with the new ones.

> [@JanStieler](#):
>
> The file doesn’t exist before.

But it exists at the time you create it. And the File::create() command should generate a file with a UUID.

---

<div class="post-metadata">

**Author:** ![JanStieler](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/janstieler/32/15642_2.png) [@JanStieler](https://forum.getkirby.com/u/JanStieler)\
**Post date:** [April 19, 2025, 12:46am UTC](https://forum.getkirby.com/t/problems-to-update-a-files-field-with-an-image/33940/7 "2025-04-19T00:46:09Z")

</div>

Okay, I understand that I have actually a mistake if it have multiple images. But I don‘t understand further why I get another UUID on the field update. In the image .txt is stored another as in the field of the page .txt.  
I test actually the script with an entry with one image.

Best

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [April 19, 2025, 8:52am UTC](https://forum.getkirby.com/t/problems-to-update-a-files-field-with-an-image/33940/8 "2025-04-19T08:52:51Z")

</div>

Is there an easy way to test your code? Like, can you share a JSON file with some data (via PM)?

---

<div class="post-metadata">

**Author:** ![JanStieler](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/janstieler/32/15642_2.png) [@JanStieler](https://forum.getkirby.com/u/JanStieler)\
**Post date:** [April 22, 2025, 10:17am UTC](https://forum.getkirby.com/t/problems-to-update-a-files-field-with-an-image/33940/9 "2025-04-22T10:17:20Z")

</div>

I’ve send you an PM.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [April 22, 2025, 11:14am UTC](https://forum.getkirby.com/t/problems-to-update-a-files-field-with-an-image/33940/10 "2025-04-22T11:14:35Z")

</div>

This works for me:

```auto
<?php

return [
	'description' => 'Import Linkedin News',
	'args' => [],
	'command' => static function ($cli): void {
		$jsonurl = $cli->prompt('Please enter a json url:');
		$kirby = $cli->kirby();
		$kirby->impersonate('kirby');
		
		//$jsonfile = 'dataset . json';
		//$json = Json::read($jsonfile);
		
		$json = Remote::get($jsonurl)->json();
		
		$newsPages = $kirby->page('news');
		
		foreach ($json as $news) {
			//finetuning output content
			$newsAuthorName = str_replace(' ', '', strtolower($news['authorName']));
			$creationDate = date('Y - m - d', strtotime($news['postedAtISO']));
			$link = '(link: ' . $news['url'] . ' text: › Linkedin Reference target: _blank rel: nofollow)';
			
			//linkedin Hashtags aus dem Text löschen
			$newsText = preg_replace(' / \s ?#\w+/', '', $news['text']);
			
			//Generate Tags Array
			$nameArray = [$news['author']['name'], $news['author']['universalName']];
			
			preg_match_all('/#\w+/', $news['text'], $hashes);
			
			$hashesWithout = array_map(function ($tag) {
				return ltrim($tag, '#');
			}, $hashes[0]);
			
			$allTags = array_merge($hashesWithout, $nameArray);
			$allTagsLower = array_map('strtolower', $allTags);
			$newsTagsArray = array_unique($allTagsLower);
			$newsTags = implode(', ', $newsTagsArray);
			
			//build the pageObject
			$newsEntry = $newsPages->createChild([
				'slug' => $newsAuthorName . '-' . $news['postedAtISO'],
				'draft' => false,
				'template' => 'news-article',
				'content' => [
					'title' => 'Linkedin News from ' . $news['authorName'] . ' on ' . $creationDate,
					'newsarticleheaderimage' => [],
					'newsarticletags' => $newsTags,
					'date' => $creationDate,
					'newsarticleauthor' => '',
					'newsarticletext' => $newsText . $link,
					'loginpage' => 'true',
					'setallowedroles' => 'Admin, Investors',
					'logintarget' => '',
					'titleoverride' => '',
					'showshare' => 'true',
					'showfooterdivider' => 'false',
					'startwhitenav' => 'false',
				],
			]);
			
			$n = 1;
			
			
			foreach (($news['images'] ?? []) as $newsImageURL) {
				// cURL verwenden, um nur die HTTP-Header zu erhalten
				$newsImageDownload = curl_init($newsImageURL);
				curl_setopt($newsImageDownload, CURLOPT_RETURNTRANSFER, true);
				$newsImageData = curl_exec($newsImageDownload);
				
				// Hole die HTTP-Header
				curl_close($newsImageDownload);
				
				if ($newsImageData === false) {
					$cli->dump('Fehler beim Abrufen des Bildes.');
					continue;
				}
				
				$tempFile = tempnam(sys_get_temp_dir(), 'img');
				file_put_contents($tempFile, $newsImageData);
				
				// MIME-Typ mit finfo_file() ermitteln
				$finfo = finfo_open(FILEINFO_MIME_TYPE);
				$mimeType = finfo_file($finfo, $tempFile);
				finfo_close($finfo);
				
				// Extrahiere den MIME-Typ aus den HTTP-Headern
				$mimeTypes = [
					'image/jpeg' => 'jpg',
					'image/png' => 'png',
					'image/gif' => 'gif',
					'image/webp' => 'webp',
					'image/svg+xml' => 'svg',
					'image/bmp' => 'bmp',
					'image/tiff' => 'tiff',
				];
				
				$newsImageFiletype = $mimeTypes[$mimeType] ?? 'jpg';
				
				try {
					$imageCreation = File::create([
						'source' => $tempFile,
						'parent' => $newsEntry,
						'filename' => $newsAuthorName . '-' . $news['postedAtISO'] . '_' . $n . '.' . $newsImageFiletype,
					]);
					// Überprüfen, ob das Bild erfolgreich erstellt wurde
					if (!$imageCreation) {
						$cli->dump('Fehler beim Erstellen des Bildes.');
						continue;
					}
					
					$newsEntry = $newsEntry->update([
						'newsarticleheaderimage' => array_merge($newsEntry->newsarticleheaderimage()->ToFiles()->pluck('uuid', ',', true), [$imageCreation->uuid()->toString()]),
					]);
					
					// Temporäre Datei löschen
					unlink($tempFile);
					
					$n++;
					
				} catch (Exception $e) {
					$cli->dump('Fehler beim Erstellen der Datei: ' . $e->getMessage());
					continue;
				}
			}
			
		}
		
		$cli->success('linkedin News imported!');
	},
];

```

---

<div class="post-metadata">

**Author:** ![JanStieler](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/janstieler/32/15642_2.png) [@JanStieler](https://forum.getkirby.com/u/JanStieler)\
**Post date:** [April 22, 2025, 12:29pm UTC](https://forum.getkirby.com/t/problems-to-update-a-files-field-with-an-image/33940/11 "2025-04-22T12:29:43Z")

</div>

Hi,

thank you!

What I have now have investigate, also ith your changed code for multiple images, is that if I have mor than one image it works but also the first image is missing.

I have checked the key output in

```php
foreach (($news['images'] ?? []) as $key => $newsImageURL) {

                $cli->dump($key); exit;

```

but it starts with key 0 so it should get all images.  
You can see the different uuid if you stop the import after the first entry.

Best

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [April 22, 2025, 3:12pm UTC](https://forum.getkirby.com/t/problems-to-update-a-files-field-with-an-image/33940/12 "2025-04-22T15:12:38Z")

</div>

Ok, I re-added the break statement to create only a single page, but still it works fine for me. The UUID assigned to the image is added to the text file

in news-article.txt:

 ![Bildschirmfoto 2025-04-22 um 17.11.30](https://europe1.discourse-cdn.com/flex017/uploads/getkirby/original/2X/c/c77412c0804431a8dab1e683fd25428e9707c127.png)

In file meta content:

 ![Bildschirmfoto 2025-04-22 um 17.10.09](https://europe1.discourse-cdn.com/flex017/uploads/getkirby/original/2X/8/8c0163cbf8b4d3b10eef72041d4d694a4bdcb551.png)

In Panel:

 ![Bildschirmfoto 2025-04-22 um 17.08.25](https://europe1.discourse-cdn.com/flex017/uploads/getkirby/original/2X/c/cfe1cfbd1f24fe98b04bf6e222ef7cf8f6d245a8.png)

As you can see, the UUID in the Newsarticleheaderimage field is identical to the meta data file of the only image.

But what is important in the changes above, is this line:

```auto
	$newsEntry = $newsEntry->update([
						'newsarticleheaderimage' => array_merge($newsEntry->newsarticleheaderimage()->ToFiles()->pluck('uuid', ',', true), [$imageCreation->uuid()->toString()]),
					]);

```

You need to store $newsEntry in a new variable, that was missing in your code above.
