Can't immediately reference a file that's been programmatically uploaded

I’m trying to programmatically create or, if already there, update pages that also contains media and is referenced from within the page through a files field.

Simplified code:

$kirby->impersonate('kirby');

// CHECK UP FRONT IF PAGE EXISTS
$newPage = $page->createChild($slug, $template, $data);
// OR
$newPage = $page->update( $data );

// CHECK UP FRONT IF FILE EXISTS, OTHERWISE
$file = $newPage->createFile($source, $filename, $template, $content);

$newPage->update([ 'files_field' => $file ]);

So basically there are three scenarios: a brand new page with a brand new file, an updated page with a brand new file and an updated page that already has that particular file.

However, only in the latter scenario I can reference the file in the files field of that page. Whenever I create a new file I can’t immediately reference it in the files field, no matter if it’s a new page or an updated one. I can only assume that the page object is kinda cached, since creating a new page object from that same page immediately after the upload yields the same result.

I’m a little bit at a loss here, maybe someone knows the solution to my problem?

Wondering that this works at all, because createFile expects an array. Same for createChild() above. Did you post your actual code or just something made up? Also, the files_field expects yaml encode file id(s), not a file object.

Sorry for the confusion, I just simplified the code for pasting it here. Full snippet below:

$kirby->impersonate('kirby');


$parent_page = $kirby->site()->find('speaker');

$page_data = [...];

// Check if page already exists by string in some field
$current_page = $parent_page->search( $id, 'id_field')->first();
if( !is_null( $current_page ) ) :

  $current_page = $parent_page->createChild([ 'slug' => $slug, 'template' => $template, 'content' => $page_data ]);
  $current_page = $current_page->changeStatus('listed');

else:

  $current_page = $current_page->update( $page_data );

endif;

// Some code to check for existence of file. If not:
$file = $current_page->createFile([
  'source' => $temp_file,
  'filename' => $name,
  'template' => 'filetemplate',
  'content' => [...]
]);
$current_page->update([ 'files_field' => Yaml::encode($file->id()) ]);

Also my mistake, there are only two scenarios:

  • a brand new page, in which case I can’t reference the brand new file in the files field
  • an updated page, in which case I can reference a brand new file in the files filed

The upload itself works perfectly fine, it’s just the reference in the files field that gives me headaches when the page itself was just created…

Hm, this should actually work, apart from some logic error in your code:

Shouldn’t this be:

// The page exists, update it!
if( ! is_null( $current_page ) ) :
  $current_page = $current_page->update( $page_data );

// The page doesn't exist, create it
else:

  $current_page = $parent_page->createChild([ 'slug' => $slug, 'template' => $template, 'content' => $page_data ]);
  $current_page = $current_page->changeStatus('listed');

endif;

I tested this code in a template which works as expected (leaving out the page update for a simplified setup):

$kirby->impersonate('kirby');

try {
  $newPage = $page->createChild([
    'slug' => 'test',
    'template' => 'test',
    'content' => ['title' => 'Some title']]);
  
  $newPage = $newPage->changeStatus('listed');
  
  $file = $newPage->createFile([
    'source' => $kirby->root('index') . '/cheesy-autumn.jpg', 
    'parent' => $page,
    'filename' => 'test.jpg', 
    'template' => 'test'
  ]);

  if ($file) {
    $newPage->update([ 'files_field' => Yaml::encode($file->id()) ]);
  }
  
} catch (Exception $e) {
  echo $e->getMessage();
}

Thanks for your help! It seems like the issue is related to the AutoID plugin, as soon as I delete the plugin everything works as expected. I’ll contact the developer / open an issue on his Github.