2

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.

Kara
  • 6,115
  • 16
  • 50
  • 57
S B
  • 1,363
  • 12
  • 21

2 Answers2

3

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.

edigu
  • 9,878
  • 5
  • 57
  • 80
0

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.

Crisp
  • 11,417
  • 3
  • 38
  • 41
  • thanks for the answer but you didn't understand my question properly – S B Jun 05 '13 at 10:45
  • Really? What have I missed? – Crisp Jun 05 '13 at 10:49
  • can you please write code which should match to my question exatly – S B Jun 05 '13 at 11:16
  • I have written code that explains how to have the service locator made available in your model class. Once you've done that, in `SomeModel`, you should then be able to get the translator by calling `$this->getServiceLocator()->get('translator');`. So again, if that doesn't answer your question, what am I missing? – Crisp Jun 05 '13 at 11:34