Advertisement

J4.0 view requires entity to exist - what's changed?

For Joomla! 4.x Coding related discussions, you could also use: http://groups.google.com/group/joomla-dev-general

Moderators: ooffick, General Support Moderators

Forum rules
Forum Rules
Absolute Beginner's Guide to Joomla! <-- please read before posting, this means YOU.
Forum Post Assistant - If you are serious about wanting help, you will use this tool to help you post.
Windows Defender SmartScreen Issues <-- please read this if using Windows 10.
Post Reply
david0058
Joomla! Enthusiast
Joomla! Enthusiast
Posts: 133
Joined: Wed Jan 20, 2016 10:58 pm

J4.0 view requires entity to exist - what's changed?

Post by david0058 » Mon Mar 03, 2025 10:41 am

I'm finishing off porting a component from J3.10 to J4.4 and have encountered a strange issue with all my entities.

In J3.10, editing an existing entity resulted in $this->item in the edit template being fully populated. I never really figured out this magic in over a decade of working with Joomla, but broadly it seems that the following takes place:

the view calls $this->get('Form')
getForm() in the model is called with loadData = true,
loadForm() in the model is called
getItem() in the model loads the data for the entity into $this->item
The populated form is displayed in the template, data shown with renderField()

When a new entity is added $this->item is null, so the default values in entity.xml are displayed.

Here's the problem: in J4.0 I get a whole bunch of "Warning: Undefined property: stdClass::xxx ..." errors because $this->item is null.

What's changed? It seems that getItem() is not called in J3.10 when adding a new item but it is in J4.4.

Do I need to hack up some sort of dummy entity to be displayed? Or is it just a bug?

Any help would be great :(

Advertisement
SharkyKZ
Joomla! Virtuoso
Joomla! Virtuoso
Posts: 3182
Joined: Fri Jul 05, 2013 10:35 am
Location: Parts Unknown

Re: J4.0 view requires entity to exist - what's changed?

Post by SharkyKZ » Mon Mar 03, 2025 12:21 pm

getItem() typically returns an instance of Joomla\CMS\Table\TableInterface, even when a record doesn't exist. But your model returns an instance of stdClass. You should inspect why.

david0058
Joomla! Enthusiast
Joomla! Enthusiast
Posts: 133
Joined: Wed Jan 20, 2016 10:58 pm

Re: J4.0 view requires entity to exist - what's changed?

Post by david0058 » Mon Mar 03, 2025 1:02 pm

This is a really good tip, and it might be the root of my "problem".

I assumed that getItem() had to return the item to be actually displayed, as generally I'm returning an object with data from multiple tables. The Table construct is a nice abstraction, but TBH I've assumed that it's just a simplistic way to read/update one table at a time so I've never used it, just implemented dummy methods for each entity. I should make time to understand how it works.

Checking the source code for ModelAdmin (libraries/src/MVC/Model/AdminModel.php), it looks like getItem() returns the item though, not a TableInterface:

J4.4:

Code: Select all

/**
   * Method to get a single record.
   *
   * @param   integer  $pk  The id of the primary key.
   *
   * @return  CMSObject|boolean  Object on success, false on failure.
   *
   * @since   1.6
   */
   public function getItem($pk = null)
    {   
        $pk    = (!empty($pk)) ? $pk : (int) $this->getState($this->getName() . '.id');
        $table = $this->getTable();

        if ($pk > 0) {
            // Attempt to load the row.
            $return = $table->load($pk);

            // Check for a table object error.
            if ($return === false) {
                // If there was no underlying error, then the false means there simply was not a row in the db for this $pk.
                if (!$table->getError()) {
                    $this->setError(Text::_('JLIB_APPLICATION_ERROR_NOT_EXIST'));
                } else {
                    $this->setError($table->getError());
                }

                return false;
            }
        }

        // Convert to the CMSObject before adding other data.
        $properties = $table->getProperties(1);
        $item       = ArrayHelper::toObject($properties, CMSObject::class);

        if (property_exists($item, 'params')) {
            $registry     = new Registry($item->params);
            $item->params = $registry->toArray();
        }

        return $item;
    }
J3.10 was pretty much identical, returning a JObject.

However, I think all this might not be relevant here, as the key difference seems to be that in J4.4 the getItem() in the model is called on Add and Edit, whereas in J3.10 it was only called on Edit. Also, on the face of it, it looks like J4.4 renderField() barfs if the field in $this->item doesn't exist whereas in J3.10 it defaulted gracefully.

Advertisement

Post Reply

Return to “Joomla! 4.x Coding”