Error when creating virtual pages

Hi,

I am setting up virtual pages using this cookbook recipe:
https://getkirby.com/docs/guide/virtual-content/virtual-pages-image-gallery
I have done this before on other sites but am getting an odd issue with this implementation - it is the first time I have done it with the latest Kirby version, which might be the issue.

Error is:

Maximum call stack size of 8339456 bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion?

The server error log is massive, as it looks to be stuck in a loop, first 30 lines are below:

[02-Apr-2024 23:30:08 Europe/London] Error: Maximum call stack size of 8339456 bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion? in /home/giantcre/rowles/kirby/src/Data/Yaml.php:60
Stack trace:
#0 /home/giantcre/rowles/kirby/src/Data/Yaml.php(47): Kirby\Data\Yaml::handler()
#1 /home/giantcre/rowles/kirby/src/Data/Data.php(81): Kirby\Data\Yaml::decode('- file://7f87is...')
#2 /home/giantcre/rowles/kirby/config/methods.php(104): Kirby\Data\Data::decode('- file://7f87is...', 'yaml')
#3 /home/giantcre/rowles/kirby/src/Content/Field.php(78): Kirby\Cms\Core->{closure}(Object(Kirby\Content\Field), 'yaml')
#4 /home/giantcre/rowles/kirby/config/methods.php(150): Kirby\Content\Field->__call('todata', Array)
#5 /home/giantcre/rowles/kirby/src/Content/Field.php(78): Kirby\Cms\Core->{closure}(Object(Kirby\Content\Field))
#6 /home/giantcre/rowles/kirby/config/methods.php(137): Kirby\Content\Field->__call('tofiles', Array)
#7 /home/giantcre/rowles/kirby/src/Content/Field.php(78): Kirby\Cms\Core->{closure}(Object(Kirby\Content\Field))
#8 /home/giantcre/rowles/site/models/artwork.php(10): Kirby\Content\Field->__call('tofile', Array)
#9 /home/giantcre/rowles/kirby/src/Cms/HasChildren.php(48): ArtworkPage->children()
#10 /home/giantcre/rowles/kirby/src/Uuid/PageUuid.php(52): Kirby\Cms\Page->childrenAndDrafts()
#11 /home/giantcre/rowles/kirby/src/Uuid/PageUuid.php(54): Kirby\Uuid\PageUuid::index(Object(ArtworkPage))
#12 /home/giantcre/rowles/kirby/src/Uuid/PageUuid.php(54): Kirby\Uuid\PageUuid::index(Object(Kirby\Cms\Page))
#13 /home/giantcre/rowles/kirby/src/Uuid/PageUuid.php(54): Kirby\Uuid\PageUuid::index(Object(Kirby\Cms\Page))
#14 /home/giantcre/rowles/kirby/src/Uuid/FileUuid.php(60): Kirby\Uuid\PageUuid::index()
#15 /home/giantcre/rowles/kirby/src/Uuid/Uuid.php(255): Kirby\Uuid\FileUuid::index()
#16 /home/giantcre/rowles/kirby/src/Uuid/ModelUuid.php(31): Kirby\Uuid\Uuid->indexes()
#17 /home/giantcre/rowles/kirby/src/Uuid/Uuid.php(335): Kirby\Uuid\ModelUuid->findByIndex()
#18 /home/giantcre/rowles/kirby/src/Cms/App.php(623): Kirby\Uuid\Uuid->model()
#19 /home/giantcre/rowles/kirby/config/methods.php(151): Kirby\Cms\App->file('file://7f87isk3...', Object(ArtworkPage))
#20 /home/giantcre/rowles/kirby/src/Content/Field.php(78): Kirby\Cms\Core->{closure}(Object(Kirby\Content\Field))
#21 /home/giantcre/rowles/kirby/config/methods.php(137): Kirby\Content\Field->__call('tofiles', Array)
#22 /home/giantcre/rowles/kirby/src/Content/Field.php(78): Kirby\Cms\Core->{closure}(Object(Kirby\Content\Field))
#23 /home/giantcre/rowles/site/models/artwork.php(10): Kirby\Content\Field->__call('tofile', Array)
#24 /home/giantcre/rowles/kirby/src/Cms/HasChildren.php(48): ArtworkPage->children()
#25 /home/giantcre/rowles/kirby/src/Uuid/PageUuid.php(52): Kirby\Cms\Page->childrenAndDrafts()
#26 /home/giantcre/rowles/kirby/src/Uuid/PageUuid.php(54): Kirby\Uuid\PageUuid::index(Object(ArtworkPage))
#27 /home/giantcre/rowles/kirby/src/Uuid/PageUuid.php(54): Kirby\Uuid\PageUuid::index(Object(Kirby\Cms\Page))
#28 /home/giantcre/rowles/kirby/src/Uuid/PageUuid.php(54): Kirby\Uuid\PageUuid::index(Object(Kirby\Cms\Page))
#29 /home/giantcre/rowles/kirby/src/Uuid/FileUuid.php(60): Kirby\Uuid\PageUuid::index()
#30 /home/giantcre/rowles/kirby/src/Uuid/Uuid.php(255): Kirby\Uuid\FileUuid::index()

The only file mentioned in the log which I have created is /site/models/artwork.php, which is below:

<?php
class ArtworkPage extends Page
{
  public function children(): Kirby\Cms\Pages
  {
    $images = [];
    
    if($this->mainImage()->isNotEmpty()):
      $images[] = [
        'slug'     => $this->mainImage()->toFile()->name(),
        'num'      => 0,
        'template' => 'lightbox-image',
        'model'    => 'lightbox-image',
      ];
    endif;

    if($this->additionalImages()->isNotEmpty()):
      foreach ($this->additionalImages()->toFiles() as $image) {
        $images[] = [
          'slug'     => $image->name(),
          'num'      => $image->sort()->value(),
          'template' => 'lightbox-image',
          'model'    => 'lightbox-image',
        ];
      }
    endif;

    return Pages::factory($images, $this);
  }
}

Line 10, which is mentioned in the error log, is 'slug' => $this->mainImage()->toFile()->name(),.

If anyone has any thoughts what might be causing this that would be awesome, I am totally stuck at the moment.

Also, I can’t see a file with this UUID in the content folder, I am not sure where this is coming from

Sorry for the bump but I am stumped by this. Has anyone has this issue before? Is there any more info I can provide that will help?

I don’t know what the issue is, but I’d start with fixing an obvious issue:

The if statement here is basically useless. It could contain anything and not be empty. But you need it to contain a valid file reference. So in case of fields that store a reference to an object, always, always, always check if you have an object:

   if($image = $this->mainImage()->toFile()):
      $images[] = [
        'slug'     => $image->name(),
        'num'      => 0,
        'template' => 'lightbox-image',
        'model'    => 'lightbox-image',
      ];
    endif;

Hi @texnixe,

Thanks for the pointer, I have made that change. Didn’t fix the issue but appreciate the guidance on improving my code.

I have done a bit of tinkering, and if I remove this section:

if($image = $this->mainImage()->toFile()):
      $images[] = [
        'slug'     => $image->name(),
        'num'      => 0,
        'template' => 'lightbox-image',
        'model'    => 'lightbox-image',
      ];
    endif;

Everything works as expected.

Update

I should clarify, I am getting a 500 error on every page of the site when that code block is present, not just on the /artwork page where the method is for

Maybe an issue with the sorting number 0, just guessing…

Or an issue with duplicate images, if main image is also in additional images?

Ok I think I have identified what is happening. There was an artwork page with that file reference in it, when I removed that page everything started working as expected. To reproduce the issue I did the following:

  1. Created a new Artist page (this is a parent page for an Artwork), and a new Artwork. Populated them as normal with images etc. and set both the parent and the child to published. All great.

  2. In the panel, chose to Delete the Artist page (which has an Artwork page as a child, which in turn has virtual children pages generated by my method above).

  3. I get the usual confirmation dialog:

  1. I enter the page title and click Delete. I get a spinning wheel for a while, then get the following screen:

  1. If I reload the Artist is still in the page listing. If I click on the Artist page in the panel, I see the panel blueprint for a brief while, with the section for Subpages (Artworks) missing, then the following screen appears:

  1. Looking in the content folder, the images and their .txt files have been deleted, but the page files remain. These still have the reference to the image in them, which was causing my original issue.

I am not sure what is going on here, could it be a permissions issue with my virtual pages? Sorry this is a huge post but wanted to cover everything!

Update

Deleting an individual Artwork page is working fine, it is just the deletion of an Artist parent page that is triggering the issue. Happy to share repo access / send a zip if this will be of help

Would it be useful for me to try to reproduce this in a minimal way using the Starterkit?

I am not sure what to do next with it, and am keen to get to a resolution if possible.

That would be helpful, indeed.

Hi,

I have replicated my setup in the Plainkit, and am getting the same error. What is the best way of getting this example to you?

You could send me a link to a zip via PM (wetransfer, dropbox or whatever you use). Or share on GitHub.

Super - that is done :dizzy:

Thanks, I downloaded the test project and could see it happen. Haven’t had a chance to debug what’s happening, and am without computer until Sunday night

No worries at all, not expecting you to look at it over the weekend. Good to hear it is happening for you as well and not just me!

Please let me know if you need anything else from me to help with this

I think the issue happens because Kirby tries to delete pages that do not exist. So the lightbox-image needs to overwrite the delete method and just return true. And in the artwork model, you also have to overwrite the delete method but haven’t tested what exactly you need to do there, maybe skip the check for subpages or something like that.

Hi,

Thanks for looking into it for me.

If you are able to provide a bit more guidance on what changes I need to make that would be great, I am unsure what to do next based on your information above.

Hi,

Sorry for bumping this but it would be great to get it sorted. I appreciate you have given some guidance above but this is at the edge of my knowledge in terms of Kirby. If you could possibly provide some more detail about what I need to do to fix the issue that would be great.

Sorry, while I know what the issue is, I still have to look into what would have to be done here in detail. I probably won’t get to it before the weekend, I’m afraid.