Date:
11 Jan 2011
Category:
Development Notes
Discuss:
5 comments

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 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, but 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

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.2beta2

  • Nils
  • 20 Jan 11, 1:57 am

Yes, we had to remove Symphony::lang() due to conflicts between the core and the installer. It has been replaced by Lang::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();.

  • Nils
  • 03 Feb 11, 1:58 am

As saveConfig() is only available in class.administration.php I think Administration::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.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details