Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If you don't want to inject the language into all of your models, then I can think of at least one other way off the top of my head.</p> <p>You could make use of an initializer. An initializer basically allows you to perform initialization tasks on services fetched through the service manager. Thus, to use this approach, you must fetch your models (at least the ones that need the language) through the service manager. This is as easy as adding them as invokables or perhaps factories if you need to inject any dependencies. For more information about initializers, you can read the <a href="http://codingexplained.com/coding/php/zend-framework/zend-framework-2-service-manager" rel="nofollow">article I wrote about the service manager</a> (scroll down to the section about initializers).</p> <p>So, what you can do is to have your models implement an interface, e.g. <code>LanguageAwareInterface</code>.</p> <pre><code>namespace User\Model; interface LanguageAwareInterface { /** * Gets the language * * @return string */ public function getLanguage(); /** * Sets the language * * @param string $language */ public function setLanguage($language); } </code></pre> <p>Then you can do like the following in your model.</p> <pre><code>namespace User\Model; class MyModel implements \User\Model\LanguageAwareInterface { /** * @var string $language The current language */ protected $language; /** * Gets the language * * @return string */ public function getLanguage() { return $this-&gt;language; } /** * Sets the language * * @param string $language */ public function setLanguage($language) { $this-&gt;language = $language; } } </code></pre> <p>If you wish, you could even make an abstract base model class that has the above code, or perhaps write a simple trait if you want to avoid extending a class. Then your models could each extend this base class, but that depends how many of your models actually need to work with the current language.</p> <p>Now for the initializer. In my article I have an example of how to add it with method calls, but chances are that you will want to do it in your configuration file (perhaps in the <code>Application</code> module if you are using the Zend Skeleton Application). You can either return an array (or point to a config file) from the module's <code>Module</code> class in the <code>getServiceConfig()</code> method, or you can just add it to the <code>YourModule/config/module.config.php</code> file under the <code>service_manager</code> key. The official documentation does not give any example of this; in fact, initializers are the only thing missing. It should, however, work.</p> <pre><code>return array( /* Other configuration here */ 'service_manager' =&gt; array( 'initializers' =&gt; array( 'language' =&gt; function($service, $sm) { // $service is the service that is being fetched from the service manager // $sm is the service manager instance if ($service instanceof \User\Model\LanguageAwareInterface) { $session = new \Zend\Session\Container('base'); if ($session-&gt;language === null) { // Fetch default language from configuration $config = $sm-&gt;get('Config'); $session-&gt;language = $config['translator']['locale']; } $service-&gt;setLanguage($session-&gt;language); } }, ), ), ); </code></pre> <p>The above initializer checks every object that is fetched from the service manager to see if it implements the interface we created above. If it does, the language can be injected. In my example, I check to see if it is set in the session and if not, fetch it from the configuration. You may have to tweak the logic depending on your exact needs. Note that the initializer will be run <em>every</em> time you fetch an object from the service manager, and thus it does add a little bit of overhead. This is, however, not significant because we are only doing a simple type check when the service does not implement the interface. Also, services are shared by default, which means that a service will only be instantiated once; subsequent requests for the same service will then reuse the previously instantiated one. This helps to limit the overhead even further.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload