Skip to content

Instantly share code, notes, and snippets.

@brendo
Created January 9, 2011 06:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brendo/771473 to your computer and use it in GitHub Desktop.
Save brendo/771473 to your computer and use it in GitHub Desktop.
A short note about `$this->_Parent`, `Administration::instance()`, `Frontend:instance` and the new `Symphony::Engine()`

Overview

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

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.

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 be Frontend or Administration. 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, by it is possible to access the same objects as the four accessors since Symphony 2.0.6.

  • Symphony::Database() and Symphony::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 the extension.driver.php) you could replicate the same logic as Symphony::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 or Administration ::instance()->ExtensionManager. Your extension should replicate some sort of Symphony::Engine() logic to be sure. Generally speaking, all backend pages (ie. Classes that extend HTMLPage) have access to Administration::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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment