Deprecation: #94956 - Public $cObj

See forge#94956

Description

Frontend plugins receive an instance of \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer when called via ContentObjectRenderer->callUserFunction(). This is typically the case for plugins called as USER or indirectly as USER_INT type.

The instance of ContentObjectRenderer has previously been set by declaring a public (!) property cObj in the consuming class.

Handing a ContentObjectRenderer instance around this way is hard to follow and has thus been deprecated: Declaring public $cObj should be avoided. Frontend plugins that need the current ContentObjectRenderer should have a public setContentObjectRenderer() method instead.

Impact

Declaring public $cObj in a class called by ContentObjectRenderer->callUserFunction() triggers a PHP E_USER_DEPRECATED error.

Affected Installations

Frontend extension classes that neither extend TYPO3\CMS\Frontend\Plugin\AbstractPlugin ("pibase") nor Extbase TYPO3\CMS\Extbase\Mvc\Controller\ActionController and have a public property cObj are affected.

Migration

When instantiating the frontend plugin, ContentObjectRenderer->callUserFunction() now checks for a public method setContentObjectRenderer() to explicitly set an instance of the ContentObjectRenderer.

Many plugins may not need this instance at all. If the ContentObjectRenderer instance used within the plugin does not rely on further ContentObjectRenderer state, for instance if it only calls stdWrap() or similar without using state like LOAD_REGISTER, the cObj class property should be avoided and an own instance of ContentObjectRenderer should be created.

Classes that do rely on current ContentObjectRenderer state should adapt their code.

Before:

class Foo
{
    public $cObj;
}

After:

class Foo
{
    protected $cObj;

    public function setContentObjectRenderer(ContentObjectRenderer $cObj): void
    {
        $this->cObj = $cObj;
    }
}