I created a sort base module in my ZF2 vendor library. So far everything is working the way I want it to work. I do have a problem. While I am able to extend the base module's controllers, I am unable to access the base service. I am using Doctrine 2 as my database layer.
After implementing the ServiceLocator, I am getting Fatal error: Call to a member function get() on a non-object in my base service file. My BaseService file is shown as below:
namespace MyResource\Service;
use Doctrine\ORM\Mapping as ORM;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class BaseService implements ServiceLocatorAwareInterface
{
/**
* Entity manager instance
*
* #var Doctrine\ORM\EntityManager
*/
protected $_em;
protected $_serviceLocator;
public function __construct()
{
$this->getEntityManager();
}
/**
* Returns an instance of the Doctrine entity manager loaded from the service
* locator
*
* #return Doctrine\ORM\EntityManager
*/
public function getEntityManager()
{
if (null === $this->_em) {
$this->_em = $this->getServiceLocator()
->get('doctrine.entitymanager.orm_default');
}
return $this->_em;
}
/**
* Set serviceManager instance
*
* #param ServiceLocatorInterface $serviceLocator
* #return void
*/
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}
/**
* Retrieve serviceManager instance
*
* #return ServiceLocatorInterface
*/
public function getServiceLocator()
{
return $this->serviceLocator;
}
}
Can anyone help?
Thanks
1):
Your property is called
protected $_serviceLocator;
but you are assigning your values to
protected $serviceLocator;
2)
Are you creating your Service via DI or the service manager? If you do then the ServiceLocator should be automatically injected for you, if you are creating it manually using the "new" keyword then it will not have the ServiceLocatior attached.
There seems to be a glitch in ZF2 .If you try setting the properties
as below the problem will be fixed. Try like this
foreach ($resultSet as $row) {
$entity = new Countrypages();
$entity->setId($row->id);
$entity->setName($row->name);
$entity->setSnippet($row->snippet);
$entity->setSortorder($row->sortorder);
$entity->setActive($row->active);
$entity->setCreated($row->created);
$entity->setModified($row->modified);
$entity->setFirstname($row->firstname);
$entity->setCreatedby($row->createdby);
$entities[] = $entity;
}
ignore this
foreach ($resultSet as $row) {
$entity = new Countrypages();
$entity->setId($row->id);
->setName($row->name);
->setSnippet($row->snippet);
->setSortorder($row->sortorder);
->setActive($row->active);
->setCreated($row->created);
->setModified($row->modified);
->setFirstname($row->firstname);
->setCreatedby($row->createdby);
$entities[] = $entity;
}
I hope this help you save your time.
You're using use use Zend\ServiceManager\ServiceManagerAwareInterface but you're implementing ServiceLocatorAwareInterface (and there's no "use" statement for that one).
Related
I have seen similar problems on Stackoverflow but none of those answers has worked for me (including clearing cache, clearing PHP opcode cache systems, de-activating and re-activating the extension). Hopefully someone can point me in the right direction.
I am running a scheduled command for an extension. At some point my command will need to call the method test() from the MyController class.
I have tried to create a reference to the class via an inheritance call AND by ALL injection methods but no matter which way I try it I always get the same issue...:
Call to a member function test() on null
Most recently I used the injection method that is not recommended, but it simplifies my example below so I'll use it for now. (VendorName and ExtensionName are obvs dummy names):
* #var \VendorName\ExtensionName\Controller\MyController
* #inject
*/
protected $mc;
public function myCommand()
{
return $this->mc->test(); //should return true
}
...and inside MyController
public function test()
{
return true;
}
The issue isn't the injection call on the command Class, but some automatically generated code on the MyController Class. It seems Extension Builder can cause the error by incorrectly creating the #inject line in the wrong place. Here is the code it created automatically:
/**
* #var \VendorName\ExtensionKey\Domain\Repository\ExampleRepository
* #inject
*/
protected $importService = null;
/**
* #inject
*/
protected $exampleRepository = null;
...that second #inject call creates the error. It should be just:
/**
* #var \VendorName\ExtensionKey\Domain\Repository\ExampleRepository
* #inject
*/
protected $importService = null;
protected $exampleRepository = null;
Unfortunately the dubugging doesn't tell you which class is causing the issue so I naturally thought it was my own code.
While creating a scope function with name 'scopeList' in the Model to return a data collection (has select) laravel throws a T_List error. Can I know why?
My code:
namespace project1;
use Illuminate\Database\Eloquent\Model;
class Lookup extends Model
{
protected $fillable = array('type','code','description','listorder');
public $timestamps = false;
/**
* List lookup entries for a given type
*
* #param $type
*
* #return \Illuminate\Support\Collection
*/
public function scopeEntries($query,$type){
return $query->select('code','description')
->where('type',$type)->get();
}
}
If instead of 'scopeEntries', I want to call it 'scopeList' I encounter an error.
I am facing problem while creating adapter object in controller file named Listcontroller.My code is
namespace Blog\Controller;
use Blog\Service\PostServiceInterface;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Db\Sql\Sql;
use Zend\Db\Adapter\Adapter;
class ListController extends AbstractActionController
{
/**
* #var \Blog\Service\PostServiceInterface
*/
protected $postService;
public function __construct(PostServiceInterface $postService)
{
$this->postService = $postService;
}
public function indexAction()
{
$adapter = new Zend\Db\Adapter\Adapter($configArray);
print_r($adapter);
//code ....
}
}
here it is serching to find Zend\Db\Adapter\Adapter inside Blog\Controller.
Error is -> Fatal error: Class 'Blog\Controller\Zend\Db\Adapter\Adapter' not found. Can anybody tell me please how can i move two folder back from above path. so that i can get proper object??
You don't need the fully qualified class name (FQCN) when instantiating a new Adapter since you declare that class path via use statement:
use Zend\Db\Adapter\Adapter;
Change this block
public function indexAction()
{
$adapter = new Zend\Db\Adapter\Adapter($configArray);
print_r($adapter);
}
to
public function indexAction()
{
$adapter = new Adapter($configArray);
print_r($adapter);
}
It should work.
Anyway, new \Zend\Db\Adapter\Adapter($configArray) also works (notice the first backslash) but its longer, harder to type and less readable than first example.
You may also want to read namespace aliasing/importing section of the documentation.
I'm trying to use Service Manager on my entity class but I don't know the best way to do that.
It's easy on a controller because we can call service manager with : $this->getServiceLocator();
But, in my entity class, even if I implements ServiceLocatorAwareInterface i can retieve ServiceManager because my entity class isn't call with the service manager :
So what is the best way :
1 - Pass serviceManager in my entity class from my controller
2 - Using ServiceManager to build my entity class
3 - ... ?
To best understand my problem, that's my code which doesn't work :
My entity class:
class Demande extends ArraySerializable implements InputFilterAwareInterface {
/../
public function getUserTable() {
if (! $this->userTable) {
$sm = $this->getServiceLocator();//<== doesn't work !
$this->userTable = $sm->get ( 'Application\Model\UserTable' );
}
return $this->userTable;
}
I wouldn't inject the ServiceManager into your model (although you can). I would rather get the ServiceManager to build your Model for you, and inject anything you need directly into the model.
Service Config:
'factories' => array(
'SomethingHere' => function($sm) {
$model= new \My\Model\Something();
return $model;
},
'\My\Model\Demande' => function($sm) {
$model= new \My\Model\Demande();
/**
* Here you use the SM to inject any dependencies you need
* into your model / service what ever..
*/
$model->setSomething($sm->get('SomethingHere'));
return $model;
},
/**
* Alternatively you can provide a class implementing
* Zend\ServiceManager\FactoryInterface
* which will provide an instance for you instad of using closures
*/
'\My\Model\DemandeDefault' => '\My\Model\DemandeFactory',
Place any of your dependencies inside the Service Manager Config, and then use that to inject any dependencies into your models, services etc for you.
An example factory class if you want to use the factory method rather than closures:
DemandeFactory.php
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class DemandeFactory implements FactoryInterface
{
/**
* Create a new Instance
*
* #param ServiceLocatorInterface $serviceLocator
* #return Demande
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
$config = $serviceLocator->get('Config'); // if you need the config..
// inject dependencies via contrustor
$model = new \My\Model\Demande($serviceLocator->get('SomethingHere'));
// or using setter if you wish.
//$model->setSomething($serviceLocator->get('SomethingHere'));
return $model;
}
}
An example Model you are trying to instantiate via the Service Manager.
Demande.php
class Demande
{
protected $_something;
/**
* You can optionally inject your dependancies via your constructor
*/
public function __construct($something)
{
$this->setSomething($something);
}
/**
* Inject your dependencies via Setters
*/
public function setSomething($something)
{
$this->_something = $something;
}
// Something will be injected for you by the Service Manager
// so there's no need to inject the SM itself.
}
In your Controller:
public function getDemande()
{
if (! $this->_demande) {
$sm = $this->getServiceLocator();
$this->_demande = $sm->get ('\My\Model\Demande');
}
return $this->_demande;
}
You could inject the SergiceManager/ServiceLocator into your models but then your models will depend on the ServiceLocator.
I am doing a project in Flash Builder using ActionScript.
I have two MXML files: login.mxml and welcome.mxml.
login.mxml:
var username:String="sample";
var password:String="sample";
welcome.mxml:
trace("welcome"+username); // o/p-welcome sample
I have to pass the username value from login.mxml to welcome.xml.
Is it possible to pass a variable value from one MXML to another MXML file? How?
Yes, it is possible. The best way though would be bind the views to an objects values.
Your views don't seem to be to be associated in terms of "one aggregates the other" but their parent (the container view) knows both. So the parent would pass an object reference to both views and when this instance is updated, the views will be notified and and updated via data binding.
If the views are completely independent from each other, it would be the most straight forward way to dispatch events through the application via the application. You should introduce a new event type (i.e. SystemEvent) which is dispatched by the Application. To keep you application clean from too many references to specific global variables used in the views, i'd suggest a delegate if you're to firm with MVC yet:
package de.guj.vila.delegates {
import flash.events.Event;
import flash.events.IEventDispatcher;
import mx.core.FlexGlobals;
import mx.core.IMXMLObject;
import mx.core.UIComponent;
public class ViewDelegate implements IEventDispatcher, IMXMLObject {
//---------------------------------------------------------------------
//
// Properties
//
//---------------------------------------------------------------------
private var _bus:IEventDispatcher;
private var _uiComponent:UIComponent;
/**
* The view which uses the delegate.
*/
public function set uiComponent(value:UIComponent):void {
_uiComponent = value;
}
//---------------------------------------------------------------------
//
// Constructor
//
//---------------------------------------------------------------------
public function ViewDelegate() {
_bus = FlexGlobals.topLevelApplication as IEventDispatcher;
}
//---------------------------------------------------------------------
//
// Implemented Methods
//
//---------------------------------------------------------------------
/**
* #inheritDoc
*
* #see flash.events.IEventDispatcher
*/
public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void {
_bus.addEventListener(type, listener, useCapture, priority, useWeakReference);
}
/**
* #inheritDoc
* #see flash.events.IEventDispatcher
*/
public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void {
_bus.removeEventListener(type, listener, useCapture);
}
/**
* #inheritDoc
* #see flash.events.IEventDispatcher
*/
public function dispatchEvent(event:Event):Boolean {
return _bus.dispatchEvent(event);
}
/**
* #inheritDoc
*
* #see flash.events.IEventDispatcher
*/
public function hasEventListener(type:String):Boolean {
return _bus.hasEventListener(type);
}
/**
* #inheritDoc
*
* #see mx.core.IMXMLObject
*/
public function initialized(document:Object, id:String):void {
uiComponent = document as UIComponent;
}
/**
* #inheritDoc
*
* #see flash.events.IEventDispatcher
*/
public function willTrigger(type:String):Boolean {
return _bus.willTrigger(type);
}
}
}
You can just stuff the in the fx:Declarations block, give it an id and dispatch events from view to view. You just have to set up the listeners. This way you can easily implement quite a clean structure, since you just have to refactor the delegate. Utilizing the delegate as a base class, you can event handle any events in the delegate, so you views stay clean and, most importantly, it's easy to port to a different MVC approach, because you already isolated view behaviour from the applications behaviour.
In the end you'll want to use an MVC framework (RobotLegs for example) to be able to scale your application easily.