ZF2 : Call a service from an external class?

1.2k views Asked by At

In my Zend Framework 2 project, I have an external lib and I want to save my information in the base with the model.

.... .... ....

EDITED MESSAGE :

I explain again my need: In my controllers, I make insertions and deletions in the database and I want to log all actions in a "t_log" table . To do it, I have thought to create an external class.

My question is: How I can call my models method from my external class ?

namespace Mynamespace;

use Firewall\Model\Logs;
use Firewall\Model\LogsTable;

class StockLog
{
    public function addLog()
    {
       $log = $this->getServiceLocator()->get('Firewall\Model\LogTable');
       $log->save('user added'); 
       die('OK');
    }
}

My model :

namespace Firewall\Model;

use Zend\Db\TableGateway\TableGateway;
use Zend\Db\Sql\Select;

class UserGroupTable
{

    protected $tableGateway;

    public function __construct(TableGateway $tableGateway)
    {
        $this->tableGateway = $tableGateway;
    }

    public function save()
    {
        // How I Can call this method from the StockLog method ?
    }
}

Thanks you !

1

There are 1 answers

5
Carlos Robles On BEST ANSWER

getServiceLocator is a function of \Zend\Mvc\Controller\AbstractActionController so it is supposed to be used in your controllers.

I dont know what your StockLog class is, but it is not extending any other class, so i guess it has not that function and your error is one step before, in the call to getSErviceLocator that is not defined, so its not returning an object.

Probably you can inject the service locator with something like

class StockLog 
{

  private $serviceLocator= null;

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


    public function add()
    {
       # Do you know how I can call the service ??
       $User = $this->serviceLocator->get('Firewall\Model\UserTable');
    }


}

and then, when you create your StockLog object, in your controller, you inject the servicelocator

public class yourController extends AbstractActionController {

   public function yourAction(){
      $mStockLog = new StockLog ();
       $mStockLog->setServiceLocator($this->getServiceLocator()); 
    /...

   }
}

Also, if you only need the 'Firewall\Model\UserTable' service, you should inject just that, instead of the serviceLocator.

At any rate you should minimice the knowledge of your model classes about the rest of the system, hving always in mind the dependency inversion principle, to get a better decoupling

UPDATE

inject the log table

namespace Mynamespace;

use Firewall\Model\Logs; use Firewall\Model\LogsTable;

class StockLog {


 private $logTable= null;

  public function setLogTable($logTable)
  {
    $this->logTable= $logTable;
  }

public function addLog()
{

   $this->logTable->save('user added'); 
   die('OK');
}

}

and then, when you create your StockLog (in your controller, or wherever you do it, before you use it) you inject the logtable object

  $mStockLog = new StockLog ();
  $mStockLog->setLogTable($this->getServiceLocator()->get('Firewall\Model\LogTable')); 

Of course, Im suposing that you configured correctly your Firewall\Model\LogTable class to be retrieved by means of the service manager, in getServiceConfig() in your Module.php

  public function getServiceConfig() {
       return array (
            'factories' => array (
                    'Firewall\Model\LogTable' => function ($sm) {
                         $logTable = //create it as you use to  
                  return $logTable;
            }  

        )

  }