Skip to content

Calling the ChannelEntry model within a ft file while editing an entry causes havoc #2117

@litzinger

Description

@litzinger

In my Advanced Categories field I need to figure out what categories are assigned to the current channel, so I end up making this call within an ft file:

$entry = ee('Model')->get('ChannelEntry', $entryId)->first();

but in doing so, it really messes up the current context of $this, as it in nullifies basically everything if I try to reference something like $this->content_id - it's just null. I'm having to capture relevant properties from the ft file in an array, make the ChannelEntry model call, then reset the properties on $this just so it would work.

I don't know what the root issue is here, probably something deep in the Model classes, but it would be nicer if the ft file actually knew what entry it was being loaded in, and better yet, have a reference to the current channel. For example, these would be a really helpful property to have in ft files:

$this->ChannelEntry;
$this->Channel;

For full context, here is some code from my ft file:

/**
     * @return array
     */
    private function getEntryCategories(): array
    {
        $entryId = $this->content_id;

        if (!$entryId) {
            return [];
        }

        if ($cache = $this->cache->get('entryCategories')) {
            return $cache;
        }

        $context = [
            'field_id' => $this->field_id,
            'field_name' => $this->field_name,
            'id' => $this->id,
            'name' => $this->name,
            'content_id' => $this->content_id,
            'content_type' => $this->content_type,
            'settings' => $this->settings,
        ];

        $entry = ee('Model')->get('ChannelEntry', $entryId)->first();
        $this->fixContext($context);

        // Cast them to a string just so it's consistent with what is return from the saved JSON object in the custom field.
        $cats = array_map(function ($value) {
            return (string) $value;
        }, $entry->Categories->pluck('cat_id'));

        $this->cache->set('entryCategories', $cats);

        return $cats;
    }

    /**
     * @param int $entryId
     * @return ChannelModel
     */
    private function getChannel($entryId = 0): ChannelModel
    {
        if ($cache = $this->cache->get('channel')) {
            return $cache;
        }

        $context = [
            'field_id' => $this->field_id,
            'field_name' => $this->field_name,
            'id' => $this->id,
            'name' => $this->name,
            'content_id' => $this->content_id,
            'content_type' => $this->content_type,
            'settings' => $this->settings,
        ];

        if ($entryId) {
            $entry = ee('Model')->get('ChannelEntry', $entryId)->first();
            $this->fixContext($context);
            $this->cache->set('channel', $entry->Channel);

            return $entry->Channel;
        }

        if (!$entryId && preg_match('/cp\/publish\/create\/(\d+)/', ee()->uri->query_string, $matches)) {
            $channel = ee('Model')->get('Channel', (int) $matches[1])->first();
            $this->fixContext($context);
            $this->cache->set('channel', $channel);

            return $channel;
        }

        if (!$entryId && preg_match('/cp\/publish\/edit\/entry\/(\d+)/', ee()->uri->query_string, $matches)) {
            $entry = ee('Model')->get('ChannelEntry', $matches[1])->first();
            $this->fixContext($context);
            $this->cache->set('channel', $entry->Channel);
        }

        return $entry->Channel;
    }

    /**
     * Fix some _really_ weird behavior where calling ee('Model')->get('ChannelEntry', $entryId)->first() resets
     * the properties on the current context of $this, which should be an instance of Advanced_categories_ft
     * Behavior seems to have started in a more recent version of EE, because this used to not be an issue.
     *
     * @param array $context
     * @return void
     */
    private function fixContext(array $context = [])
    {
        foreach ($context as $property => $value) {
            $this->{$property} = $value;
        }
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions