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.
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 static accessors to Symphony::Database()
and Symphony::Configuration()
. These allow extensions to reference these objects regardless of the instance Symphony is operating in (Frontend
or Administration
).
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 use $this->_Parent
to handle the correct context, which will be either Administration::instance()
or Frontend::instance()
. It should be noted that their are slight differences between the two, which can be better explained by reading through the documentation of both classes and noting the different variables and function implementations. 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 the 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 is it possible (though not recommended) to access the Symphony instance through $this->_Parent->_Parent
.
Moving forward, the goal is to remove $this->_Parent
from Symphony as it is now redundant. In Symphony 2.2, $this->_Parent
is replaced by a new accessor Symphony::Engine()
, which will return the correct context. Symphony::Engine()
works by checking if Administration
exists, or if Frontend
exists and returning the instance based on that check. The reason this is (traditionally) a reliable check is Symphony's index.php
only includes the Administration
/Frontend
files based off the $_GET['mode']
. This parameter is generated in the .htaccess
from the mod_rewrite rules. Basically if /symphony/
is present, the mode
is set to Administration
and then that class is included, otherwise it's omission will include the Frontend
class.
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 now recommended to use $context['parent']
or Symphony::Engine()
.
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
or 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.
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.
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, by 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