?
avatar NickSdot
NickSdot
18 Apr 2018

I want to prepare my extension for J!4 and I just run into an potential issue / changed behavior.

Steps to reproduce the issue

  1. Set a registry value in function A
  2. Try to get it in function B

Example code:

/* 
 * component/myComponent/views/view/view.html.php
 * 
 */

public function myTask()
{
    // here all code before, not relevant here
    
    // set dummy
    $data->value = 'dummy';

    // fire plugin trigger
    $pluginResponseValidation = $dispatcher->trigger('onDataValidation', $data);

    // here some code to throw Exception and Message if not valid, also save response data in DB

    // fire second plugin trigger of same plugin
    $pluginResponseProcess = $dispatcher->trigger('onDataProcess', $data);

}

/* 
 * plugins/group/myPlugin/plugin.php
 * 
 */

use \Joomla\Registry\Registry;

public function onDataValidation($data)
{
    if(empty($data))
    {
        return false;
    }

    $result = $this->_validateData($data);
    
    return $result;
}


public function onDataProcess($data)
{
    if(empty($data))
    {
        return false;
    }

    $result = $this->_processData($data);

    return $result;
}

private function _validateData($data)
{
    // new Registry which results in excepted behavior
    $registry1 = Registry::getInstance('myID');

    // get Registry value
    $value1 = $registry1->set('my.path.value1', '1');
    
    // dump data
    echo '<pre>';
    var_dump($value1); // value IS available, OK
    echo '</pre>';
    
    
    // new Registry
    $registry2 = new Registry;

    // get Registry value
    $value2 = $registry2->set('my.path.value2', '2');

    // dump data
    echo '<pre>';
    var_dump($value2); // value IS available, OK
    echo '</pre>';

    // bla blub, sample code, not relevant here
    return $result = '';
}


private function _processData($data)
{
    // new Registry which results in excepted behavior
    $registry1 = Registry::getInstance('myID');

    // get Registry value
    $value1 = $registry1->get('my.path.value1');

    // dump data
    echo '<pre>';
    var_dump($value1); // value IS available, OK
    echo '</pre>';

    // new Registry which SUCCESS
    $registry2 = new Registry;

    // get registry value
    $value2 = $registry2->get('my.path.value2');

    // dump data
    echo '<pre>';
    var_dump($value2);  // value IS NOT available, NOT OK
    echo '</pre>';

    // bla blub, sample code, not relevant here
    
    return $result = '';
}

Expected result

$value2 should be NOT NULL in _processData

Actual result

$value2 is always NULL in _processData

System information (as much as possible)

PHP Version | 7.0.24
Web Server | Apache/2.4.29
WebServer to PHP Interface | cgi-fcgi
Joomla! Version | Joomla! 3.8.6 Stable [ Amani ] 13-March-2018 14:00 GMT
Joomla! Platform Version | Joomla Platform 13.1.0 Stable [ Curiosity ] 24-Apr-2013 00:00 GMT

Additional comments

All in the same view, same task, on after form submit.

I am aware of this and I think I am followed it:
https://github.com/joomla-framework/registry
https://docs.joomla.org/Potential_backward_compatibility_issues_in_Joomla_4

Is this is a wanted behavior?
Or a bug?
Or do I do something wrong?
Any thoughts? Thanks!

avatar NickSdot NickSdot - open - 18 Apr 2018
avatar joomla-cms-bot joomla-cms-bot - change - 18 Apr 2018
Labels Added: ?
avatar joomla-cms-bot joomla-cms-bot - labeled - 18 Apr 2018
avatar franz-wohlkoenig franz-wohlkoenig - change - 18 Apr 2018
Category Plugins
avatar SharkyKZ
SharkyKZ - comment - 18 Apr 2018

Your code is wrong. Use Registry::getInstance() in both cases.

avatar NickSdot
NickSdot - comment - 18 Apr 2018

Thanks for your answer.

Bit confusing, because phpDOC says deprecated.
So the phpDOC is wrong/misleading?

	/**
	 * Returns a reference to a global Registry object, only creating it
	 * if it doesn't already exist.
	 *
	 * This method must be invoked as:
	 * <pre>$registry = Registry::getInstance($id);</pre>
	 *
	 * @param   string  $id  An ID for the registry instance
	 *
	 * @return  Registry  The Registry object.
	 *
	 * @since   1.0
	 * @deprecated  2.0  Instantiate a new Registry instance instead
	 */
	public static function getInstance($id)
	{
		if (empty(self::$instances[$id]))
		{
			self::$instances[$id] = new self;
		}

		return self::$instances[$id];
	}

Also found this:
#18641

avatar franz-wohlkoenig franz-wohlkoenig - change - 18 Apr 2018
Status New Discussion
avatar SharkyKZ
SharkyKZ - comment - 18 Apr 2018

Put it in construct?

public function __construct(&$subject, $config)
{
	parent::__construct($subject, $config);

	$this->registry = new Registry;
}
avatar NickSdot
NickSdot - comment - 18 Apr 2018

Thanks again for your answer!

I tried this. Yes, if I handle it with the constructor it works.

In my case I decided now anyways that it is better to move this specific value to the Session Object instead into the Registry. So, I do not really looking for a workaround.

But I wondering if this behavior is happening on purpose or not.
Because, as I wrote before, it works with the 'old' Singleton way without using the constructor.

If we assume that I do not miss something and that this change is on purpose, I would consider this at least as worth to add to:
https://docs.joomla.org/Potential_backward_compatibility_issues_in_Joomla_4

And maybe even better to the deprecated message in the phpDoc of

public static function getInstance($id)

Maybe @mbabker can add something to this conversation?

avatar mbabker
mbabker - comment - 18 Apr 2018

As clearly indicated on the docs wiki page the page is a work in progress. I would leave that page specifically to the CMS issues for now, we are building upgrade documentation for Framework packages, this case with the Registry is covered in https://github.com/joomla-framework/registry/blob/2.0-dev/docs/v1-to-v2-update.md and when we are ready to release these pages will be consolidated onto the Framework website.

avatar NickSdot
NickSdot - comment - 18 Apr 2018

Thanks for your answer @mbabker.

this case with the Registry is covered in https://github.com/joomla-framework/registry/blob/2.0-dev/docs/v1-to-v2-update.md and when we are ready to release these pages will be consolidated onto the Framework website.

Yes, of course. I also read this and knew that it is deprecated.
What I wondering is just, whether the (changed) behavior is on purpose or not.

As clearly indicated on the docs wiki page the page is a work in progress.

So I can assume that the new behavior itself is on purpose?

If so, I would also assume that feedback and hints to make the docs and info pages better are welcome as well. The intention of my question was not to critisize that any docs are outdated or not ready yet.
Please don't get me wrong.

avatar mbabker
mbabker - comment - 18 Apr 2018

Both of your $registry2 = new Registry; lines create new Registry objects that don't reference the same instance (if you do a var_dump(spl_object_hash($registry2)); after both of those lines you'll see that they have two different hashes meaning they are two different objects).

Both of your $registry1 = Registry::getInstance('myID'); lines will reference the same Registry object because the getInstance() method supports singleton object storage, the singleton storage is removed from 4.0 (Framework 2.0).

So if you need a shared Registry instance to be re-used between more than one method in a class, you need to make it a class property like hinted at above. And if you need to share it between classes, you'll need to come up with your own logic on how to do that.

avatar NickSdot
NickSdot - comment - 18 Apr 2018

Thanks @mbabker.

avatar NickSdot NickSdot - change - 18 Apr 2018
Status Discussion Closed
Closed_Date 0000-00-00 00:00:00 2018-04-18 12:30:16
Closed_By NickSdot
avatar NickSdot NickSdot - close - 18 Apr 2018

Add a Comment

Login with GitHub to post a comment