cms icon indicating copy to clipboard operation
cms copied to clipboard

Fieldtype field()->parent() populated with wrong entry

Open naabster opened this issue 1 year ago • 3 comments

Bug description

Since 4.51.0 the field()->parent() is set to some other entry.

I have a custom fieldtype which needs the entry id to populate data from an API. I do this in the preload() method using $this->field()->parent() Since 4.51.0 this resolves some random entry, but not the correct one. Most of the time the last entry in the structure tree (I noticed the bug in a structured collection).

How to reproduce

Use a custom fieldtype and check the parent:

<?php

namespace App\Fieldtypes;

use Statamic\Fields\Fieldtype;

class Sections extends Fieldtype
{
    public function preload()
    {
        ray($this->field()?->parent());
        ray($this->field()?->parent()->id());

        $parentEntry = $this->field()?->parent()->id();
        self::appendConfigField('parent_entry', [
            'type' => 'text',
            'default' => $parentEntry,
        ]);
        return ['parent_entry' => $parentEntry];
    }
}

Logs

No response

Environment

php 8.3.3
laravel 10.46.0
statamic 4.51.0

Installation

Fresh statamic/statamic site via CLI

Antlers Parser

Runtime (default)

Additional details

No response

naabster avatar Mar 01 '24 12:03 naabster

Since 4.51.0 this resolves some random entry, but not the correct one. Most of the time the last entry in the structure tree (I noticed the bug in a structured collection).

I've just tested this in my sandbox site and wasn't able to replicate the issue 🤔

Where were you seeing the wrong entries being populated - in the entry publish form?

duncanmcclean avatar Mar 04 '24 13:03 duncanmcclean

@duncanmcclean it took me a while to narrow it down further: i could replicate the issue in a fresh install with a structured collection with dates enabled. So both structure and publish dates need to be enabled. Also use a proper cache driver (like redis), not the array cache driver!

Collection:

title: testcollection
template: default
layout: layout
revisions: false
date: true
sort_dir: asc
date_behavior:
  past: public
  future: private
preview_targets:
  -
    label: Entry
    url: '{permalink}'
    refresh: true
structure:
  root: true
  max_depth: 3

Blueprint:

title: testcollection
tabs:
  main:
    display: Main
    sections:
      -
        fields:
          -
            handle: title
            field:
              type: text
              required: true
              validate:
                - required
          -
            handle: content
            field:
              type: markdown
              display: Content
              localizable: true
          -
            handle: author
            field:
              type: users
              display: Author
              default: current
              localizable: true
              max_items: 1
          -
            handle: template
            field:
              type: template
              display: Template
              localizable: true
          -
            handle: parent_test_field
            field:
              type: parent_test
              display: 'Parent Test Field'
              listable: hidden
              instructions_position: above
              visibility: visible
              replicator_preview: true
              hide_display: false
  sidebar:
    display: Sidebar
    sections:
      -
        fields:
          -
            handle: slug
            field:
              type: slug
              localizable: true
              validate: 'max:200'
          -
            handle: parent
            field:
              type: entries
              collections:
                - testcollection
              max_items: 1
              listable: false
              localizable: true

App/Fieldtypes/ParentTest.php

<?php

namespace App\Fieldtypes;

use Statamic\Fields\Fieldtype;

class ParentTest extends Fieldtype
{
    public function preload()
    {
        $parentEntry = $this->field()?->parent()->id();
        self::appendConfigField('parent_entry', [
            'type' => 'text',
            'default' => $parentEntry,
        ]);
        return ['parent_entry' => $parentEntry];
    }
}

resources/js/components/ParentTest.vue

<template>

    <div>
        <p>ID: {{ config.parent_entry }}</p>
    </div>

</template>

<script>
export default {

    mixins: [Fieldtype],

    data() {
        return {
            //
        };
    }

};
</script>

You would expect that the ID shown on the publishing form is the ID of the entry. On the first page load after clearing cache and stache it more or less is, afterwards it is some other ID. So if your collection only has one entry everything is fine 🤷

naabster avatar Mar 04 '24 17:03 naabster

Possibly related to #9633

jasonvarga avatar Mar 05 '24 14:03 jasonvarga