The inner workings of the magical $this->_Parent
have always been a bit of an unknown to Symphony developers and therefore, several ways have cropped up of doing the same things. Starting with Symphony 2.2, there is now a recommendation of how extensions should correctly use this variable.
Overview
In the early Symphony 2 days, $this->_Parent
was used to manage a catalogue of all the available Managers and other objects such as Configuration
and Database
so extensions could use these instead of creating their own. Efforts were made in Symphony 2.0.6 to help cleanup this catalogue structure (which is memory intensive) by introducing two static accessors, Symphony::Database()
and Symphony::Configuration()
. These allowed extensions to reference these objects regardless of the instance Symphony was operating in (Frontend
or Administration
). There are slight differences between the two instances, which can be better explained by reading through the documentation of both classes taking note of the different variables and function implementations.
A typical Field extension works in both instances, functions such as displayPublishPanel
work in Administration
, others such as appendFormattedElement
work in Frontend
. Extensions are initialised with a variable, $this->_Parent
, which allows extension developers to not have to worry about what context the Extension is operating in and instead use $this->_Parent
to handle the correct context whether it be Administration::instance()
or Frontend::instance()
. There is a confusing case in which $this->_Parent
references two different things depending on the file. In extension.driver.php
, $this->_Parent
will be a Symphony instance(), however in the Field class, $this->_Parent
will be an instance of the FieldManager
. To combat this, the Field
class has $this->_engine
which will return the same as the traditional $this->_Parent
. An interesting sidenote to this is that because of the catalogue structure in a Field class it is possible (though not recommended) to access the Symphony instance through $this->_Parent->_Parent
.
Moving Forward
Moving forward, the goal is to remove $this->_Parent
from Symphony as it is now redundant. In Symphony 2.2, $this->_Parent
can be replaced by a new accessor Symphony::Engine()
, which will return the correct instance context. Symphony::Engine()
works by checking if Administration
class exists, or if Frontend
class exists and returns the correct instance based on that check. The reason this is (traditionally) a reliable check is Symphony’s index.php
only includes the Administration
/Frontend
classes based off the value of$_GET['mode']
. This parameter is generated in the .htaccess
through the mod_rewrite rules. Basically if the current URL starts (after the domain) with /symphony/
, the $_GET['mode']
is set to Administration
and that class is included, otherwise it’s omission will result in the Frontend
class being included.
Extensions should no longer have to include the Frontend
class to accomplish tasks thanks to Symphony::Engine()
. It should be noted that this functionality has existed in versions of Symphony prior to 2.2 through the delegate callback context. Delegates return an associative array of variables that can be changed. An undocumented (until now) variable is parent
, which returns an instance of either Administration
or Frontend
. Extensions are recommended to use Symphony::Engine()
or, less preferred, $context['parent']
.
You’ll often see Manager initialised like this new SectionManager($this->_Parent)
. To be honest, I don’t really know why this done, but I do know that it is essentially just passing around an instance of Administration
, Frontend
or a Manager instance. The Symphony Team will be looking at removing this ‘passaround’ notion in the near future (next release of Symphony) due to the arrival of the new accessors.
Takeaways
Symphony 2.2
Symphony::Database()
is the recommended way to access the Database object.$this->Database
is deprecated and will be removed in the next Symphony version.Symphony::Configuration()
is the recommended way to access the Configuration object.$this->Configuration
is deprecated and will be removed in the next Symphony version.Symphony::ExtensionManager()
is the recommended way to access the ExtensionManager object.$this->ExtensionManager
will be removed in the next Symphony version.Symphony::Engine()
is the recommended way to access correct Symphony object, whether that beFrontend
orAdministration
.Field->_engine
is deprecated and will be removed in the next Symphony version.$this->_Parent
is deprecated and will be removed ASAP. If any extension developers are using this variable and it cannot be replaced by one of the 4 accessors, the Symphony Team would like to know ASAP.
Versions prior to Symphony 2.2 (but greater than 2.0.6)
Although there is a way forward, many of us have extensions that work (and we’d like them to continue to work) in older versions of Symphony. It may be surprising, but it is possible to access the same objects as the four accessors since Symphony 2.0.6.
Symphony::Database()
andSymphony::Configuration()
were introduced in Symphony 2.0.6. Unless you wish to for your extension to be compatible to versions prior to 2.0.6 it is recommended that all references to the Database or Configuration objects be through these accessors in of$this->Database
or$this->Configuration
.For all delegate callbacks, a backwards compatible
Symphony::Engine()
is$context['parent']
which has been around since the start of the 2.x branch. If there is logic outside of a delegate callback that requires a Symphony instance (and is not theextension.driver.php
) you could replicate the same logic asSymphony::Engine()
in your extension constructor. Keep in the mind that Field objects already have$this->_engine
Since 2.0.6 the ExtensionManager can be accessed via
Frontend::instance()->ExtensionManager
orAdministration ::instance()->ExtensionManager
. Your extension should replicate some sort ofSymphony::Engine()
logic to be sure. Generally speaking, all backend pages (ie. Classes that extendHTMLPage
) have access toAdministration::instance()
. However, if your extension is a:- Field, it can be found using
$this->_engine->ExtensionManager
- Datasource or Event, it can be found using
$this->_Parent->ExtensionManager
- Field, it can be found using
I hope that helps ease any confusion and helps out while developing your next extension!
Comments
What about
Symphony::lang()
, is that gone too? I found it give error with my extensions in S2.2beta2Yes, we had to remove
Symphony::lang()
due to conflicts between the core and the installer. It has been replaced byLang::get()
.Now that I use
Symphony::Configuration()
, how do I save the config to the file?Before 2.2 I had to use
Administration::instance()->saveConfig();
.As
saveConfig()
is only available inclass.administration.php
I thinkAdministration::instance()->saveConfig()
is still the correct way to do this.Symphony::Engine()->saveConfig()
will work as well, but only if it’s used in administration context so its usage doesn’t really make sense.Administration::instance()->saveConfig()
is still correct :)Symphony::Engine()
is more for things where you know the function is available in both contexts (eg.isLoggedIn()
.Create an account or sign in to comment.