I want to prepare my extension for J!4 and I just run into an potential issue / changed behavior.
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 = '';
}
$value2 should be NOT NULL in _processData
$value2 is always NULL in _processData
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
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!
Labels |
Added:
?
|
Category | ⇒ | Plugins |
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
Status | New | ⇒ | Discussion |
Put it in construct?
public function __construct(&$subject, $config)
{
parent::__construct($subject, $config);
$this->registry = new Registry;
}
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?
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.
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.
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.
Status | Discussion | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2018-04-18 12:30:16 |
Closed_By | ⇒ | NickSdot |
Your code is wrong. UseRegistry::getInstance()
in both cases.