Zend Framework 2: PostService::savePost() must be compatible with Blog\Service\PostServiceInterface::savePost(Blog\Model\PostInterface $blog) issue - zend-framework2

I am facing this issue while adding blog post in Zend Framework 2 using the link Making use of Forms and Fieldsets. I have double checked whether anything is missed by me. Can anybody help where i am going wrong or anything missing please. As i am new Zend Framework its little hard to track the issue.
Fatal error: Declaration of Blog\Service\PostService::savePost() must be compatible with Blog\Service\PostServiceInterface::savePost(Blog\Model\PostInterface $blog) in D:\xampp\htdocs\zf\module\Blog\src\Blog\Service\PostService.php on line 9
The required file to fix this bug is given below:
<?php
// Filename: /module/Blog/src/Blog/Service/PostService.php
namespace Blog\Service;
use Blog\Model\PostInterface;//this clause is missing in the tutorial link
use Blog\Mapper\PostMapperInterface;
class PostService implements PostServiceInterface {
/**
* #var \Blog\Mapper\PostMapperInterface
*/
protected $postMapper;
/**
* #param PostMapperInterface $postMapper
*/
public function __construct(PostMapperInterface $postMapper) {
$this->postMapper = $postMapper;
}
/**
* {#inheritDoc}
*/
public function findAllPosts() {
return $this->postMapper->findAll();
}
/**
* {#inheritDoc}
*/
public function findPost($id) {
return $this->postMapper->find($id);
}
/**
* {#inheritDoc}
*/
public function savePost(PostInterface $post) {
return $this->postMapper->save($post);
}
}

I if saw correctly, it looks like that in the example you are following, in the PostServiceClass, a use Blog\Model\PostInterface; clause is missing.
This is causing the PostInterface used in the savePost method to be a Blog\Service\PostInterface and not a Blog\Model\PostInterface and hence the implementation of the savePost method is not complatible with its declaration in the interface

Related

Typo3 Call to a member function on null

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.

Zend Framework 2 - How to give declare folder path in terms of "use" and "namespace"

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.

how to add form validation from controller in zend framework 2

I tried to add a validation from my controller like below. but it always shows this
if ($request->getPost('ownerType') == "Company") {
$form->getInputFilter()->get('companyName')->getValidatorChain()->addValidator('required');
}
shows error. I confused with below error.
Catchable fatal error: Argument 1 passed to Zend\Validator\ValidatorChain::addValidator() must implement interface Zend\Validator\ValidatorInterface, string given, called in E:\xampp\htdocs\hossbrag\module\WebApp\src\WebApp\Controller\JobController.php on line 177 and defined in E:\xampp\htdocs\hossbrag\vendor\zendframework\zendframework\library\Zend\Validator\ValidatorChain.php on line 100
My controller is here
<?php
namespace WebApp\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use WebApp\Entity\User;
use Zend\View\Model\JsonModel;
use vendor\mpdf\mpdf;
class JobController extends AuthenticatedController
{
public function createAction()
{
$form = new \WebApp\Form\JobpostingForm();
$form->get('companyName')->setValueOptions($company);
$checkAgreement = true;
$request = $this->getRequest();
if ($request->getPost('ownerType') == "Company") {
$form->getInputFilter()->get('companyName')->getValidatorChain()->addValidator('required');
}
}
}
What should to change in my controller to get appropriate solution.
If you encounter such a clear error, simply check out the sources ;)
First one to check would be Zend\Validator\ValidatorInterface. The Error shows you, that a Class implementing this interface is excepted. Looking at the code you'll see, the function wants a Class, not just a string.
But since you're used to ZF a little it becomes clear that you know there's other ways to add stuff. So let's take a look at Zend\InputFilter\InputFilter#add(). You'll see that the first param of the add() function indeed asks for a class implementing ValidatorInterface. But it also accepts some other stuff:
/**
* Add an input to the input filter
*
* #param array|Traversable|InputInterface|InputFilterInterface $input
* #param null|string $name
* #return InputFilter
*/
public function add($input, $name = null)
{
//...
}
It also accepts array, Traversable, InputInterface and InputFilterInterface. So choices are there.
Now, i have never done this myself and i sincerely hope this works (if not i suck!), but assuming you're using the array-syntax, all you have to do is this:
[...]->getValidatorChain()->add(array(
'type' => 'Zend\Validator\NotEmpty'
));
Let me know if this worked out for you ;)

Call to a member function get()

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).

How to pass a variable value from one MXML to another MXML?

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.

Resources