Question

How to get translator in model?

Inside view we can get translator using this code

$this->translate('Text')

Inside controller we can get translator using this code

$translator=$this->getServiceLocator()->get('translator');

$translator->translate("Text") ;

But how to get translator in model?

I'd tried so many ways to get service locator in models 2 of those

1)Using MVC events

    $e=new MvcEvent();
    $sm=$e->getApplication()->getServiceManager();
    $this->translator = $sm->get('translator');

if i pring $sm it is showing null. but it works fine in Model.php onBootstrap

2)Created one model which implements ServiceLocatorAwareInterface SomeModel.php

    <?php

namespace Web\Model;

use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class SomeModel implements ServiceLocatorAwareInterface
{
    protected $services;

    public function setServiceLocator(ServiceLocatorInterface $locator)
    {
        $this->services = $locator;
    }

    public function getServiceLocator()
    {
        return $this->services;
    }
}

and used that inside my model

        $sl = new SomeModel();
        $sm=$sl->getServiceManager();
        var_dump($sm); exit;
        $this->translator = $sm->get('translator');

this is also printing null.

Was it helpful?

Solution

If you don't need the servicemanager instance in your model, simply inject translator instance to it.

For example:

// Your model's constructor

class MyModel {
  // Use the trait if your php version >= 5.4.0
  use \Zend\I18n\Translator\TranslatorAwareTrait;

  public function __construct( $translator )
  {
     $this->setTranslator( $translator ); 
  }

  public function modelMethodWhichNeedsToUseTranslator()
  {
    // ...
    $text = $this->getTranslator()->translate('lorem ipsum');
    // ...
  }
}

When you creating your model first time on service or controller level

class someClass implements ServiceLocatorAwareInterface {
    public function theMethodWhichCreatesYourModelInstance()
    {
    // ...
    $sm = $this->getServiceLocator();
    $model = new \Namespace\MyModel( $sm->get('translator') )
    // ...
    }
}

If you need to instantiate your model (new MyModel();) on multiple methods/classes, consider to writing a factory for it.

Here is a nice article about Dependency Injection and PHP by Ralph Schindler for more detailed comments about this approach.

OTHER TIPS

For your Model class to be ServiceLocatorAware, you not only need to implement the interface, you also need to make your model a service of the service manager, and fetch the model from there.

Add your model to the service manager, since it doesn't appear to need any constructor params, it's invokable, so you can add it to the invokables array in service manager config. You can do that by using the getServiceConfig() method in your Module class...

class Module
{
    public function getServiceConfig()
    {
        return array(
            'invokables' => array(
                'SomeModel' => 'Fully\Qualified\ClassName\To\SomeModel',
            ),
        );
    }
}

Then, instead of calling the new keyword to create your model instance, you fetch it from the service manager, for instance, by calling the getServiceLocator() method in a controller action...

public function fooAction()
{
     $sm = $this->getServiceLocator();
     $model = $sm->get('SomeModel');
}

When your model is fetched from the service manager, a service initializer will look to see if it implements the ServiceLocatorAwareInterface and automatically call setServiceLocator() if it does, passing it an instance of the service manager.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top